Fixed <stdio.h> file and dereferencing bugs#807
Conversation
|
|
||
| size_t fwrite(const void *__restrict ptr, size_t size, size_t count, FILE *__restrict stream); | ||
|
|
||
| long int ftell(FILE *stream) __attribute__((__warn_unused_result__)); |
There was a problem hiding this comment.
long int is archaic, so I have replaced it with just plain long.
| uint8_t index = stream->slot - 1; | ||
| _file_streams[index].eof = 0; | ||
| _file_streams[index].err = 0; |
There was a problem hiding this comment.
fixed off by one error, since stream->slot is 1-indexed instead of 0-indexed
|
|
||
| _file_streams[slot - 1].slot = 0; | ||
|
|
||
| int status = ti_Close(slot); |
There was a problem hiding this comment.
Only closing the file in libc if and only if fileioc was able to successfully close the file
| if (stream == NULL || stream == stdin || stream == stdout || stream == stderr) | ||
| { | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
We cannot dereference stream if it is NULL, stdin, stdout, or stderr
|
|
||
| if (c == EOF) | ||
| { | ||
| stream->eof = 1; |
There was a problem hiding this comment.
I fixed things so stdin, stdout, and stderr are not dereferenced here
| size_t bytes_read = 0; | ||
|
|
||
| for (; len > 0; len--) | ||
| for (; len --> 0;) |
There was a problem hiding this comment.
This is a more common idiom for writing the decrementing count
There was a problem hiding this comment.
No it fucking isn't
| } | ||
|
|
||
| return ti_Seek((int)offset, origin, stream->slot); | ||
| return (ti_Seek((int)offset, origin, stream->slot) == EOF) ? -1 : 0; |
There was a problem hiding this comment.
fseek returns 0 on success and non-zero otherwise
| // ti_Tell shouldn't return a value greater than OS_VAR_MAX_SIZE (65512) unless an error occurs | ||
| uint16_t ret = ti_Tell(stream->slot); | ||
| // Convert a result of UINT16_MAX to -1L, leaving other results the same | ||
| return ((uint16_t)ret + 1) - 1L; |
There was a problem hiding this comment.
This had an integer promotion bug. (uint16_t)ret + 1 results in int, not uint16_t
| C(fseek(file, 0, SEEK_END) == 0); | ||
| int file_size = ftell(file); | ||
| fseek(file, 0, SEEK_SET); | ||
| C(fseek(file, 0, SEEK_SET) == 0); |
There was a problem hiding this comment.
Added some basic return value checks. Mostly important fseek since it returned the wrong value prior.
Fixed the following issues:
Also fixed:
FILE * streamwhen it isNULL,stdin,stdout, orstderr.fseekandftell