tmontaigu / dbase-rs

Rust library to read & write dBase files.
MIT License
29 stars 30 forks source link

Failed to read .dbf file due to cursor misalignment #11

Closed casperhart closed 3 years ago

casperhart commented 3 years ago

Hello, I have a .dbf file which failed to read using dbase-rs using the following code:

extern crate dbase;

fn main() -> Result<(), dbase::Error> {
    let mut reader = dbase::Reader::from_path("myfile.dbf")?;
    for record_result in reader.iter_records() {
        let record = record_result?;
        for (name, value) in record {
            println!("name: {}, value: {:?}", name, value);
        }
    }
    Ok(())
}

And produced the following error:

Error: ReadingError { record_num: 0, kind: ParseIntError(ParseIntError { kind: InvalidDigit }), FieldInfo { Name: DATE, Field Type: dbase::Date } }

I did some investigation and found the issue is that the reader and data were misaligned by one character. I.e. a field that is meant to be read as "value" would instead be read as " valu". This would cause a date field to fail to parse and throw an error.

This appeared to be because the call to Reader::new resulted in source with a cursor at position 1409, when the value offset_to_first_record was 1410 for this particular file. Adding the following code at the end of the Reader::new function in reading.rs appeared to fix the issue, ensuring that the source cursor position is correct:

source.seek(SeekFrom::Start(u64::from(offset_to_first_record))).map_err(|error| Error::io_error(error, 0))?;

I don't know why this issue presents itself for my .dbf file and not for others (perhaps it doesn't follow the spec exactly?). However, other DBF readers appear to have no trouble, which is why I've opened the issue.

tmontaigu commented 3 years ago

Hello,

Are you able to share the file ?

Otherwise I looked at the changes you made in your fork and they look good, so if you want to open PR you can 😃

casperhart commented 3 years ago

Hi, unfortunately I can't share the file as the data is somewhat sensitive, but I will open a PR. Thanks