kshedden / datareader

Read binary SAS (SAS7BDAT) and Stata (dta) files in the Go (Golang) programming language. Also provides command line tools for working with these file formats.
BSD 3-Clause "New" or "Revised" License
22 stars 12 forks source link

SAD7BDAT.read_next_page does not handle EOF. #5

Closed jacklionheart closed 5 years ago

jacklionheart commented 5 years ago

(This is probably true for other file types, but I haven't tested them.)

In sas7bdat.go:818, the code assumes that any non-nil error should void the read, but that is not true for io.EOF. The golang io package says explicitly: """ // When Read encounters an error or end-of-file condition after // successfully reading n > 0 bytes, it returns the number of // bytes read. It may return the (non-nil) error from the same call // or return the error (and n == 0) from a subsequent call. // An instance of this general case is that a Reader returning // a non-zero number of bytes at the end of the input stream may // return either err == EOF or err == nil. """

Thus, if a File interface chooses to return EOF immediately on the last, positive-byte-sized read rather than waiting to return EOF with a 0-byte read (as the s3 filesystem I am using does), then this breaks the SAS7BDAT reader.

I believe a simple fix would be to change the line (sas7bdat.go:818) to:

    if err != nil && err != io.EOF {

Would that work?

kshedden commented 5 years ago

Thanks for the report. I made the change you suggested and it did not break any of my tests (which are not comprehensive and do not cover the behavior that is causing you trouble). So I guess this change is at worst harmless, and I have committed it. If you continue to have issues like this let me know. I wonder if there are other places where the same thing may happen.

jacklionheart commented 5 years ago

Thank you for the quick fix.