Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FS position method return valid position on error, should return -1 #9992

Closed
1 task done
drmpf opened this issue Jul 7, 2024 · 6 comments · Fixed by #10002
Closed
1 task done

FS position method return valid position on error, should return -1 #9992

drmpf opened this issue Jul 7, 2024 · 6 comments · Fixed by #10002
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@drmpf
Copy link
Contributor

drmpf commented Jul 7, 2024

Board

All

Device Description

ESP32
ESP8266 code base has the same issue

Hardware Configuration

all

Version

latest master (checkout manually)

IDE Name

Arduino

Operating System

Windows 10

Flash frequency

40Mhz

PSRAM enabled

yes

Upload speed

115200

Description

Current code returns valid file position on error, should return invalid position, i.e. -1

Current code is

size_t File::position() const {
  if (!*this) {
    return 0;
  }
  return _p->position();
}

should be

size_t File::position() const {
  if (!*this) {
    return -1;  // <<<<<<<<<<<<<<<<
  }
  return _p->position();
}

Sketch

Not needed

Debug Message

None

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@drmpf drmpf added the Status: Awaiting triage Issue is waiting for triage label Jul 7, 2024
@lbernstone
Copy link
Contributor

size_t is unsigned int. Unless you just opened the file or did a seek to 0, it will be unusual to get a 0 position.

@drmpf
Copy link
Contributor Author

drmpf commented Jul 7, 2024

The problem is 0 is being used as an ERROR return, but it is actually a valid return.
It is not an unusual return value.

It is perfectly valid to have one method work on the file handle and then pass it to another method for further processing and have the second method test to see if the file has been rewound, i.e. check the position returns 0.

In that case, if position() returns 0, how do I tell if the file has been rewound or if there is an error?

Other FS libraries return -1, which, cast to size_t, will result in a very large number which can be used to detect the error.
On the other hand the Arduino String library uses an int return for indexOf() and returns -1 for errors.
int (32bits for ESP32) would probably be large enough to use for the position() return.

@me-no-dev
Copy link
Member

why would you depend on position to distinguish valid from invalid file? We could return -1 but this IMHO is invalid, because result is given in unsigned int. Feel free to add a pull request with the change.

@drmpf
Copy link
Contributor Author

drmpf commented Jul 9, 2024

As a user of this API, I would expect a return in the valid range, i.e. 0 to some high number, to indicate that the file is actually in that position.
As it is if 0 is returned I don't know if it is safe to let the code proceed.

The 'fixes' for this seem to be either
i) return an out of range result, e.g. -1, cast to the result type, on error
ii) return an error via an 'out of band process', such as throwing an exception or set something like ferror.
iii) fix it in the documenation

I think i) is the preferrable way and this is what the Seeed Arduino FS library does.
However you don't seem keen on this.
ii) seems to out of keeping with the 'Arduino' style
If you don't want to fix this in the code, then iii) should be chosen to at least fixed it in the documentation for this library.
That is the description for this call should be documented along the lines of

/** position() 
** returns unsigned int
** if >0 returned, then that is the current position in the file
** if 0 returned, then the file state is indeterminate.  The position may be zero or the file may be invalid.
*/

strtol seems use all three 'fixes' to give you the worst of all worlds

Return value -- long
    If successful, an integer value corresponding to the contents of str is returned.
    If the converted value falls out of range of corresponding return type, a range error occurs (setting errno to ERANGE) and LONG_MAX, LONG_MIN is returned.
    If no conversion can be performed, ​0​ is returned. 

For some errors it returns an extreme value
For some errors it indicates the error via the 'out of band' variable ERANGE
For some errors it just returns 0 and documents that that may or may not be a valid result.

How would the maintainers of this library like to proceed?

@me-no-dev
Copy link
Member

@drmpf I checked the very latest Arduino SD library (not ours, official SD lib) and it returns -1 as you propose. So such change would be accepted here, since our FS is modeled after the Arduino SD library.

drmpf added a commit to drmpf/arduino-esp32 that referenced this issue Jul 10, 2024
Fix for error return from position()
Issue espressif#9992
me-no-dev pushed a commit that referenced this issue Jul 10, 2024
* position_fix

Fix for error return from position()
Issue #9992

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
@TD-er
Copy link
Contributor

TD-er commented Sep 20, 2024

See #10360

This should be reverted as it causes all kinds of issues, since position() is being used in functions like peek() , seekDir() and available().
Some of which return this as an int or hand it over to a function which expects a signed type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants