HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

getline substitute that will enforce 'n' as limit of characters read

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
enforcereadgetlinelimitsubstitutewillthatcharacters

Problem

Following from a discussion with others on StackOverflow concerning the issue with 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 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.