summaryrefslogtreecommitdiff
path: root/src/internal/shgetc.h
AgeCommit message (Collapse)AuthorLines
2019-03-14fix crash/out-of-bound read in sscanfRich Felker-1/+1
commit d6c855caa88ddb1ab6e24e23a14b1e7baf4ba9c7 caused this "regression", though the behavior was undefined before, overlooking that f->shend=0 was being used as a sentinel for "EOF" status (actual EOF or hitting the scanf field width) of the stream helper (shgetc) functions. obviously the shgetc macro could be adjusted to check for a null pointer in addition to the != comparison, but it's the hot path, and adding extra code/branches to it begins to defeat the purpose. so instead of setting shend to a null pointer to block further reads, which no longer works, set it to the current position (rpos). this makes the shgetc macro work with no change, but it breaks shunget, which can no longer look at the value of shend to determine whether to back up. Szabolcs Nagy suggested a solution which I'm using here: setting shlim to a negative value is inexpensive to test at shunget time, and automatically re-trips the cnt>=shlim stop condition in __shgetc no matter what the original limit was.
2018-09-15fix undefined behavior in strto* via FILE buffer pointer abuseRich Felker-2/+25
in order to produce FILE objects to pass to the intscan/floatscan backends without any (prohibitively costly) extra buffering layer, the strto* functions set the FILE's rend (read end) buffer pointer to an invalid value at the end of the address space, or SIZE_MAX/2 past the beginning of the string. this led to undefined behavior comparing and subtracting the end pointer with the buffer position pointer (rpos). the comparison issue is easily eliminated by using != instead of <. however the subtractions require nontrivial changes: previously, f->shcnt stored the count that would have been read if consuming the whole buffer, which required an end pointer for the buffer. the purpose for this was that it allowed reading it and adding rpos-rend at any time to get the actual count so far, and required no adjustment at the time of __shgetc (actual function call) since the call would only happen when reaching the end of the buffer. to get rid of the dependency on rend, instead offset shcnt by buf-rpos (start of buffer) at the time of last __shlim/__shgetc call. this makes for slightly more work in __shgetc the function, but for the inline macro it's still just as easy to compute the current count. since the scan helper interfaces used here are a big hack, comments are added to document their contracts and what's going on with their implementations.
2018-09-12apply hidden visibility to various remaining internal interfacesRich Felker-2/+2
2012-04-16fix broken shgetc limiter logic (wasn't working)Rich Felker-1/+1
2012-04-13use macros instead of inline functions in shgetc.hRich Felker-20/+4
at -Os optimization level, gcc refuses to inline these functions even though the inlined code would roughly the same size as the function call, and much faster. the easy solution is to make them into macros.
2012-04-10add "scan helper getc" and rework strtod, etc. to use itRich Felker-0/+25
the immediate benefit is a significant debloating of the float parsing code by moving the responsibility for keeping track of the number of characters read to a different module. by linking shgetc with the stdio buffer logic, counting logic is defered to buffer refill time, keeping the calls to shgetc fast and light. in the future, shgetc will also be useful for integrating the new float code with scanf, which needs to not only count the characters consumed, but also limit the number of characters read based on field width specifiers. shgetc may also become a useful tool for simplifying the integer parsing code.