patterncMinor
getline substitute that will enforce 'n' as limit of characters read
Viewed 0 times
enforcereadgetlinelimitsubstitutewillthatcharacters
Problem
Following from a discussion with others on StackOverflow concerning the issue with
In in the version below,
The function is fairly self-explanatory,
So I'm posting here to see if there are flaws I haven't picked up on. I've tried to test as many corner cases as I could imagine (I haven't considered
getline not limiting input and happily reallocating until enough space for a sizable nefarious string, I picked around at a substitute that I could put in place that mimics getline's behavior. The primary objective was to enforce a length restriction through size_t *n rather than simply updating n with the current allocation size. If n was specified as 0 no limit on input would apply. In in the version below,
n is not updated with current allocation size, but used for allocating n + 1 bytes to cover the allocation for reading n characters from stream. If n is 0, then initial allocation is set to an initial value (e.g. #define SZINIT 64, or it could easily be a default local variable in the function itself). Reading stops when n is reached, or if n=0 the lineptr is reallocated until \n or EOF.The function is fairly self-explanatory,
n is preserved unchanged in the function to serve as a flag for whether reading stops at n or whether the lineptr is reallocated. maxc is the maximum characters that can be read before reallocation. Reallocation follows the traditional 2 * current approach and maxc is updated to reflect the current allocation. If reallocation occurs, the allocation is always greater than the number of characters read which should ever prevent writing beyond the end of the buffer. If reading stops at n, the remaining characters in the input buffer are discarded.So I'm posting here to see if there are flaws I haven't picked up on. I've tried to test as many corner cases as I could imagine (I haven't considered
SZINIT being set to 0, as I just thought about that possibility). Other than that, give it a look and let me know what issues you see and whether there are glaring efficiency issues I can correct without overly complicating the code. (efficiency has not been the primary focus, but testing shows that for small Solution
Types
It seems that
The variable
As it stands, if for some reason
Possible memory leak
If any of the calls to realloc fail, the previous allocation will be lost because you will no longer have any pointer to it. I'm not sure how important this is to you though.
It seems that
n is used only as an input value, so I would just make it a size_t instead of a pointer. If you are keeping it a pointer to make this function look like getline(), then I would suggest making it a const size_t *.The variable
nchr is strange because you declare it signed but cast it to unsigned everywhere. I assume that the only reason it is signed in the first place is because the function itself returns a signed value. In that case, I think that the function should have a maximum bytes read of SSIZE_T_MAX and nchr should not be allowed to exceed that value. Either that or change the return value to unsigned.As it stands, if for some reason
nchr wraps around and becomes negative, this line will start writing outside the buffer:(*s)[nchr++] = c;Possible memory leak
If any of the calls to realloc fail, the previous allocation will be lost because you will no longer have any pointer to it. I'm not sure how important this is to you though.
Code Snippets
(*s)[nchr++] = c;Context
StackExchange Code Review Q#91019, answer score: 5
Revisions (0)
No revisions yet.