mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2025-05-27 14:05:11 +02:00
stdio: fix scanf bounds breaking strto*
Mostly an initialization problem. But I also optimized the check by making the bound a maximal unsigned integer when there is no bound, since __scanf_peek() is used a lot.
This commit is contained in:
parent
d8a55b728d
commit
c776336a0d
9 changed files with 29 additions and 25 deletions
|
@ -6,12 +6,11 @@
|
|||
|
||||
void __scanf_start(struct __scanf_input *in)
|
||||
{
|
||||
|
||||
if(in->fp)
|
||||
in->buffer = fgetc(in->fp);
|
||||
else {
|
||||
in->buffer = (*in->str ? *in->str : EOF);
|
||||
in->str += (in->buffer != 0);
|
||||
in->str += (in->buffer != EOF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +285,7 @@ int __scanf(
|
|||
// we need to assign the read char to the corresponding pointer
|
||||
if (!skip) {
|
||||
char *c = (char *) va_arg( *args, char* );
|
||||
if (in->readmaxlength==-1) {
|
||||
if (in->readmaxlength==(unsigned int)-1) {
|
||||
for(;;) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
|
@ -305,7 +304,7 @@ int __scanf(
|
|||
}
|
||||
}
|
||||
else {
|
||||
for(int u=0; u<in->readmaxlength; u++) {
|
||||
for(unsigned int u=0; u<in->readmaxlength; u++) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
else if (__is_allowed( temp )) {
|
||||
|
@ -332,7 +331,7 @@ int __scanf(
|
|||
|
||||
else
|
||||
{
|
||||
if (in->readmaxlength==-1) {
|
||||
if (in->readmaxlength==(unsigned int)-1) {
|
||||
for(;;) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
|
@ -345,7 +344,7 @@ int __scanf(
|
|||
}
|
||||
}
|
||||
else {
|
||||
for(int u=0; u<in->readmaxlength; u++) {
|
||||
for(unsigned int u=0; u<in->readmaxlength; u++) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
else if (__is_allowed( temp )) __scanf_in( in );
|
||||
|
@ -546,13 +545,13 @@ int __scanf(
|
|||
char temp;
|
||||
if (!skip) {
|
||||
char *c = (char *) va_arg( *args, char* );
|
||||
if (in->readmaxlength==-1) {
|
||||
if (in->readmaxlength==(unsigned int)-1) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
else *c = __scanf_in( in );
|
||||
}
|
||||
else {
|
||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
||||
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
else *c++ = __scanf_in( in );
|
||||
|
@ -560,7 +559,7 @@ int __scanf(
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (in->readmaxlength==-1) {
|
||||
if (in->readmaxlength==(unsigned int)-1) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
else {
|
||||
|
@ -569,7 +568,7 @@ int __scanf(
|
|||
}
|
||||
}
|
||||
else {
|
||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
||||
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF) return EOF;
|
||||
else __scanf_in( in );
|
||||
|
@ -590,7 +589,7 @@ int __scanf(
|
|||
__purge_space( in );
|
||||
if (!skip) {
|
||||
char *c = (char *) va_arg( *args, char* );
|
||||
if (in->readmaxlength==-1) {
|
||||
if (in->readmaxlength==(unsigned int)-1) {
|
||||
loopstring:
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF && curstrlength==0) return validrets;
|
||||
|
@ -605,7 +604,7 @@ int __scanf(
|
|||
}
|
||||
}
|
||||
else {
|
||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
||||
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF && curstrlength==0) return validrets;
|
||||
if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) {
|
||||
|
@ -620,7 +619,7 @@ int __scanf(
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (in->readmaxlength==-1) {
|
||||
if (in->readmaxlength==(unsigned int)-1) {
|
||||
loopstringskip:
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF && curstrlength==0) return validrets;
|
||||
|
@ -632,7 +631,7 @@ int __scanf(
|
|||
}
|
||||
}
|
||||
else {
|
||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
||||
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||
temp = __scanf_peek( in );
|
||||
if (temp==EOF && curstrlength==0) return validrets;
|
||||
if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) goto loopstringendskip;
|
||||
|
|
|
@ -19,7 +19,7 @@ struct __scanf_input {
|
|||
FILE *fp;
|
||||
|
||||
// max char to read from the input stream as per user length modifier
|
||||
int readmaxlength;
|
||||
unsigned int readmaxlength;
|
||||
int currentlength;
|
||||
|
||||
// total number of char read so far in the current call of a XYscanf() function (to return a %n when required)
|
||||
|
@ -55,9 +55,8 @@ static inline int __scanf_in(struct __scanf_input *__in)
|
|||
/* Peek the next byte without advancing. */
|
||||
static inline int __scanf_peek(struct __scanf_input *__in)
|
||||
{
|
||||
if (__in->readmaxlength==-1 || __in->currentlength<__in->readmaxlength )
|
||||
return __in->buffer;
|
||||
else return 0;
|
||||
return ((unsigned)__in->currentlength < __in->readmaxlength)
|
||||
? __in->buffer : EOF;
|
||||
}
|
||||
|
||||
/* Close the input by unsending the buffer once finished. */
|
||||
|
|
|
@ -7,7 +7,7 @@ double strtod(char const * restrict ptr, char ** restrict endptr)
|
|||
if(endptr)
|
||||
*endptr = (char *)ptr;
|
||||
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||
__scanf_start(&in);
|
||||
int err = __strto_fp(&in, &d, NULL, NULL);
|
||||
__scanf_end(&in);
|
||||
|
|
|
@ -7,7 +7,7 @@ float strtof(char const * restrict ptr, char ** restrict endptr)
|
|||
if(endptr)
|
||||
*endptr = (char *)ptr;
|
||||
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||
__scanf_start(&in);
|
||||
int err = __strto_fp(&in, NULL, &f, NULL);
|
||||
__scanf_end(&in);
|
||||
|
|
|
@ -7,7 +7,13 @@ long int strtol(char const * restrict ptr, char ** restrict endptr, int base)
|
|||
if(endptr)
|
||||
*endptr = (char *)ptr;
|
||||
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
||||
struct __scanf_input in = {
|
||||
.str = ptr,
|
||||
.fp = NULL,
|
||||
.readmaxlength = -1,
|
||||
.currentlength = 0,
|
||||
.readsofar = 0,
|
||||
};
|
||||
__scanf_start(&in);
|
||||
int err = __strto_int(&in, base, &n, NULL, false);
|
||||
__scanf_end(&in);
|
||||
|
|
|
@ -7,7 +7,7 @@ long double strtold(char const * restrict ptr, char ** restrict endptr)
|
|||
if(endptr)
|
||||
*endptr = (char *)ptr;
|
||||
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||
__scanf_start(&in);
|
||||
int err = __strto_fp(&in, NULL, NULL, &ld);
|
||||
__scanf_end(&in);
|
||||
|
|
|
@ -8,7 +8,7 @@ long long int strtoll(char const * restrict ptr, char ** restrict endptr,
|
|||
if(endptr)
|
||||
*endptr = (char *)ptr;
|
||||
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||
__scanf_start(&in);
|
||||
int err = __strto_int(&in, base, NULL, &n, false);
|
||||
__scanf_end(&in);
|
||||
|
|
|
@ -8,7 +8,7 @@ unsigned long int strtoul(char const * restrict ptr, char ** restrict endptr,
|
|||
if(endptr)
|
||||
*endptr = (char *)ptr;
|
||||
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||
__scanf_start(&in);
|
||||
int err = __strto_int(&in, base, (long *)&n, NULL, true);
|
||||
__scanf_end(&in);
|
||||
|
|
|
@ -8,7 +8,7 @@ unsigned long long int strtoull(char const * restrict ptr,
|
|||
if(endptr)
|
||||
*endptr = (char *)ptr;
|
||||
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
||||
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||
__scanf_start(&in);
|
||||
int err = __strto_int(&in, base, NULL, (long long *)&n, true);
|
||||
__scanf_end(&in);
|
||||
|
|
Loading…
Add table
Reference in a new issue