mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2025-05-28 14:35:12 +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)
|
void __scanf_start(struct __scanf_input *in)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(in->fp)
|
if(in->fp)
|
||||||
in->buffer = fgetc(in->fp);
|
in->buffer = fgetc(in->fp);
|
||||||
else {
|
else {
|
||||||
in->buffer = (*in->str ? *in->str : EOF);
|
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
|
// we need to assign the read char to the corresponding pointer
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
char *c = (char *) va_arg( *args, char* );
|
char *c = (char *) va_arg( *args, char* );
|
||||||
if (in->readmaxlength==-1) {
|
if (in->readmaxlength==(unsigned int)-1) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
|
@ -305,7 +304,7 @@ int __scanf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(int u=0; u<in->readmaxlength; u++) {
|
for(unsigned int u=0; u<in->readmaxlength; u++) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
else if (__is_allowed( temp )) {
|
else if (__is_allowed( temp )) {
|
||||||
|
@ -332,7 +331,7 @@ int __scanf(
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (in->readmaxlength==-1) {
|
if (in->readmaxlength==(unsigned int)-1) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
|
@ -345,7 +344,7 @@ int __scanf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(int u=0; u<in->readmaxlength; u++) {
|
for(unsigned int u=0; u<in->readmaxlength; u++) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
else if (__is_allowed( temp )) __scanf_in( in );
|
else if (__is_allowed( temp )) __scanf_in( in );
|
||||||
|
@ -546,13 +545,13 @@ int __scanf(
|
||||||
char temp;
|
char temp;
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
char *c = (char *) va_arg( *args, char* );
|
char *c = (char *) va_arg( *args, char* );
|
||||||
if (in->readmaxlength==-1) {
|
if (in->readmaxlength==(unsigned int)-1) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
else *c = __scanf_in( in );
|
else *c = __scanf_in( in );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
else *c++ = __scanf_in( in );
|
else *c++ = __scanf_in( in );
|
||||||
|
@ -560,7 +559,7 @@ int __scanf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (in->readmaxlength==-1) {
|
if (in->readmaxlength==(unsigned int)-1) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
else {
|
else {
|
||||||
|
@ -569,7 +568,7 @@ int __scanf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF) return EOF;
|
if (temp==EOF) return EOF;
|
||||||
else __scanf_in( in );
|
else __scanf_in( in );
|
||||||
|
@ -590,7 +589,7 @@ int __scanf(
|
||||||
__purge_space( in );
|
__purge_space( in );
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
char *c = (char *) va_arg( *args, char* );
|
char *c = (char *) va_arg( *args, char* );
|
||||||
if (in->readmaxlength==-1) {
|
if (in->readmaxlength==(unsigned int)-1) {
|
||||||
loopstring:
|
loopstring:
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF && curstrlength==0) return validrets;
|
if (temp==EOF && curstrlength==0) return validrets;
|
||||||
|
@ -605,7 +604,7 @@ int __scanf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF && curstrlength==0) return validrets;
|
if (temp==EOF && curstrlength==0) return validrets;
|
||||||
if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) {
|
if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) {
|
||||||
|
@ -620,7 +619,7 @@ int __scanf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (in->readmaxlength==-1) {
|
if (in->readmaxlength==(unsigned int)-1) {
|
||||||
loopstringskip:
|
loopstringskip:
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF && curstrlength==0) return validrets;
|
if (temp==EOF && curstrlength==0) return validrets;
|
||||||
|
@ -632,7 +631,7 @@ int __scanf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( int u = 0; u < in->readmaxlength; u++ ) {
|
for( unsigned int u = 0; u < in->readmaxlength; u++ ) {
|
||||||
temp = __scanf_peek( in );
|
temp = __scanf_peek( in );
|
||||||
if (temp==EOF && curstrlength==0) return validrets;
|
if (temp==EOF && curstrlength==0) return validrets;
|
||||||
if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) goto loopstringendskip;
|
if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) goto loopstringendskip;
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct __scanf_input {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
// max char to read from the input stream as per user length modifier
|
// max char to read from the input stream as per user length modifier
|
||||||
int readmaxlength;
|
unsigned int readmaxlength;
|
||||||
int currentlength;
|
int currentlength;
|
||||||
|
|
||||||
// total number of char read so far in the current call of a XYscanf() function (to return a %n when required)
|
// 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. */
|
/* Peek the next byte without advancing. */
|
||||||
static inline int __scanf_peek(struct __scanf_input *__in)
|
static inline int __scanf_peek(struct __scanf_input *__in)
|
||||||
{
|
{
|
||||||
if (__in->readmaxlength==-1 || __in->currentlength<__in->readmaxlength )
|
return ((unsigned)__in->currentlength < __in->readmaxlength)
|
||||||
return __in->buffer;
|
? __in->buffer : EOF;
|
||||||
else return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the input by unsending the buffer once finished. */
|
/* Close the input by unsending the buffer once finished. */
|
||||||
|
|
|
@ -7,7 +7,7 @@ double strtod(char const * restrict ptr, char ** restrict endptr)
|
||||||
if(endptr)
|
if(endptr)
|
||||||
*endptr = (char *)ptr;
|
*endptr = (char *)ptr;
|
||||||
|
|
||||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||||
__scanf_start(&in);
|
__scanf_start(&in);
|
||||||
int err = __strto_fp(&in, &d, NULL, NULL);
|
int err = __strto_fp(&in, &d, NULL, NULL);
|
||||||
__scanf_end(&in);
|
__scanf_end(&in);
|
||||||
|
|
|
@ -7,7 +7,7 @@ float strtof(char const * restrict ptr, char ** restrict endptr)
|
||||||
if(endptr)
|
if(endptr)
|
||||||
*endptr = (char *)ptr;
|
*endptr = (char *)ptr;
|
||||||
|
|
||||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||||
__scanf_start(&in);
|
__scanf_start(&in);
|
||||||
int err = __strto_fp(&in, NULL, &f, NULL);
|
int err = __strto_fp(&in, NULL, &f, NULL);
|
||||||
__scanf_end(&in);
|
__scanf_end(&in);
|
||||||
|
|
|
@ -7,7 +7,13 @@ long int strtol(char const * restrict ptr, char ** restrict endptr, int base)
|
||||||
if(endptr)
|
if(endptr)
|
||||||
*endptr = (char *)ptr;
|
*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);
|
__scanf_start(&in);
|
||||||
int err = __strto_int(&in, base, &n, NULL, false);
|
int err = __strto_int(&in, base, &n, NULL, false);
|
||||||
__scanf_end(&in);
|
__scanf_end(&in);
|
||||||
|
|
|
@ -7,7 +7,7 @@ long double strtold(char const * restrict ptr, char ** restrict endptr)
|
||||||
if(endptr)
|
if(endptr)
|
||||||
*endptr = (char *)ptr;
|
*endptr = (char *)ptr;
|
||||||
|
|
||||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||||
__scanf_start(&in);
|
__scanf_start(&in);
|
||||||
int err = __strto_fp(&in, NULL, NULL, &ld);
|
int err = __strto_fp(&in, NULL, NULL, &ld);
|
||||||
__scanf_end(&in);
|
__scanf_end(&in);
|
||||||
|
|
|
@ -8,7 +8,7 @@ long long int strtoll(char const * restrict ptr, char ** restrict endptr,
|
||||||
if(endptr)
|
if(endptr)
|
||||||
*endptr = (char *)ptr;
|
*endptr = (char *)ptr;
|
||||||
|
|
||||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||||
__scanf_start(&in);
|
__scanf_start(&in);
|
||||||
int err = __strto_int(&in, base, NULL, &n, false);
|
int err = __strto_int(&in, base, NULL, &n, false);
|
||||||
__scanf_end(&in);
|
__scanf_end(&in);
|
||||||
|
|
|
@ -8,7 +8,7 @@ unsigned long int strtoul(char const * restrict ptr, char ** restrict endptr,
|
||||||
if(endptr)
|
if(endptr)
|
||||||
*endptr = (char *)ptr;
|
*endptr = (char *)ptr;
|
||||||
|
|
||||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||||
__scanf_start(&in);
|
__scanf_start(&in);
|
||||||
int err = __strto_int(&in, base, (long *)&n, NULL, true);
|
int err = __strto_int(&in, base, (long *)&n, NULL, true);
|
||||||
__scanf_end(&in);
|
__scanf_end(&in);
|
||||||
|
|
|
@ -8,7 +8,7 @@ unsigned long long int strtoull(char const * restrict ptr,
|
||||||
if(endptr)
|
if(endptr)
|
||||||
*endptr = (char *)ptr;
|
*endptr = (char *)ptr;
|
||||||
|
|
||||||
struct __scanf_input in = { .str = ptr, .fp = NULL };
|
struct __scanf_input in = { .str = ptr, .fp = NULL, .readmaxlength = -1 };
|
||||||
__scanf_start(&in);
|
__scanf_start(&in);
|
||||||
int err = __strto_int(&in, base, NULL, (long long *)&n, true);
|
int err = __strto_int(&in, base, NULL, (long long *)&n, true);
|
||||||
__scanf_end(&in);
|
__scanf_end(&in);
|
||||||
|
|
Loading…
Add table
Reference in a new issue