diff --git a/src/opcodes.c b/src/opcodes.c index 6410fc05c27aa1291eca812320c2e4a521760874..d0ed78db3ba7e6151ad91d5a7f467fd9985db84f 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -429,7 +429,7 @@ static INT32 low_sscanf(INT32 num_arg) int match_len; struct svalue sval; int e,cnt,matches,eye,arg; - int no_assign; + int no_assign,field_length; char set[256]; struct svalue *argp; @@ -473,245 +473,279 @@ static INT32 low_sscanf(INT32 num_arg) } #endif + no_assign=0; + field_length=-1; + cnt++; if(cnt>=match_len) error("Error in sscanf format string.\n"); - if(match[cnt]=='*') + while(1) { - no_assign=1; - cnt++; - if(cnt>=match_len) - error("Error in sscanf format string.\n"); - }else{ - no_assign=0; - } + switch(match[cnt]) + { + case '*': + no_assign=1; + cnt++; + if(cnt>=match_len) + error("Error in sscanf format string.\n"); + continue; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + char *t; + field_length=STRTOL(match+cnt,&t,10); + cnt=t-match; + continue; + } - switch(match[cnt]) - { - case 'c': - if(eye>=input_len) return matches; - sval.type=T_INT; - sval.subtype=NUMBER_NUMBER; - sval.u.integer=EXTRACT_UCHAR(input+eye); - eye++; - break; + case 'c': + if(field_length == -1) field_length = 1; + if(eye+field_length > input_len) return matches; + sval.type=T_INT; + sval.subtype=NUMBER_NUMBER; + sval.u.integer=0; + while(--field_length >= 0) + { + sval.u.integer<<=8; + sval.u.integer|=EXTRACT_UCHAR(input+eye); + eye++; + } + break; - case 'd': - { - char * t; - - if(eye>=input_len) return matches; - sval.u.integer=STRTOL(input+eye,&t,10); - if(input + eye == t) return matches; - eye=t-input; - sval.type=T_INT; - sval.subtype=NUMBER_NUMBER; - break; - } + case 'd': + { + char * t; + + if(eye>=input_len) return matches; + sval.u.integer=STRTOL(input+eye,&t,10); + if(input + eye == t) return matches; + eye=t-input; + sval.type=T_INT; + sval.subtype=NUMBER_NUMBER; + break; + } - case 'x': - { - char * t; - - if(eye>=input_len) return matches; - sval.u.integer=STRTOL(input+eye,&t,16); - if(input + eye == t) return matches; - eye=t-input; - sval.type=T_INT; - sval.subtype=NUMBER_NUMBER; - break; - } + case 'x': + { + char * t; + + if(eye>=input_len) return matches; + sval.u.integer=STRTOL(input+eye,&t,16); + if(input + eye == t) return matches; + eye=t-input; + sval.type=T_INT; + sval.subtype=NUMBER_NUMBER; + break; + } - case 'o': - { - char * t; - - if(eye>=input_len) return matches; - sval.u.integer=STRTOL(input+eye,&t,8); - if(input + eye == t) return matches; - eye=t-input; - sval.type=T_INT; - sval.subtype=NUMBER_NUMBER; - break; - } + case 'o': + { + char * t; + + if(eye>=input_len) return matches; + sval.u.integer=STRTOL(input+eye,&t,8); + if(input + eye == t) return matches; + eye=t-input; + sval.type=T_INT; + sval.subtype=NUMBER_NUMBER; + break; + } - case 'D': - { - char * t; - - if(eye>=input_len) return matches; - sval.u.integer=STRTOL(input+eye,&t,0); - if(input + eye == t) return matches; - eye=t-input; - sval.type=T_INT; - sval.subtype=NUMBER_NUMBER; - break; - } + case 'D': + { + char * t; + + if(eye>=input_len) return matches; + sval.u.integer=STRTOL(input+eye,&t,0); + if(input + eye == t) return matches; + eye=t-input; + sval.type=T_INT; + sval.subtype=NUMBER_NUMBER; + break; + } - case 'f': - { - char * t; + case 'f': + { + char * t; - if(eye>=input_len) return matches; - sval.u.float_number=STRTOD(input+eye,&t); - if(input + eye == t) return matches; - eye=t-input; - sval.type=T_FLOAT; + if(eye>=input_len) return matches; + sval.u.float_number=STRTOD(input+eye,&t); + if(input + eye == t) return matches; + eye=t-input; + sval.type=T_FLOAT; #ifdef __CHECKER__ - sval.subtype=0; + sval.subtype=0; #endif - break; - } + break; + } - case 's': - if(cnt+1>=match_len) - { - sval.type=T_STRING; + case 's': + if(field_length != -1) + { + if(input_len - eye < field_length) + return matches; + + sval.type=T_STRING; #ifdef __CHECKER__ - sval.subtype=0; + sval.subtype=0; #endif - sval.u.string=make_shared_binary_string(input+eye,input_len-eye); - break; - }else{ - char *end_str_start; - char *end_str_end; - char *s=0; /* make gcc happy */ - char *p=0; /* make gcc happy */ - int start,contains_percent_percent, new_eye; - - start=eye; - end_str_start=match+cnt+1; - - s=match+cnt+1; - test_again: - if(*s=='%') + sval.u.string=make_shared_binary_string(input+eye,field_length); + eye+=field_length; + break; + } + + if(cnt+1>=match_len) { - s++; - if(*s=='*') s++; - switch(*s) + sval.type=T_STRING; +#ifdef __CHECKER__ + sval.subtype=0; +#endif + sval.u.string=make_shared_binary_string(input+eye,input_len-eye); + eye=input_len; + break; + }else{ + char *end_str_start; + char *end_str_end; + char *s=0; /* make gcc happy */ + char *p=0; /* make gcc happy */ + int start,contains_percent_percent, new_eye; + + start=eye; + end_str_start=match+cnt+1; + + s=match+cnt+1; + test_again: + if(*s=='%') { - case 'n': s++; - goto test_again; + if(*s=='*') s++; + switch(*s) + { + case 'n': + s++; + goto test_again; - case 's': - error("Illigal to have two adjecent %%s.\n"); - return 0; /* make gcc happy */ + case 's': + error("Illigal to have two adjecent %%s.\n"); + return 0; /* make gcc happy */ - /* sscanf("foo-bar","%s%d",a,b) might not work as expected */ - case 'd': - for(e=0;e<256;e++) set[e]=1; - for(e='0';e<='9';e++) set[e]=0; - set['-']=0; - goto match_set; - - case 'o': - for(e=0;e<256;e++) set[e]=1; - for(e='0';e<='7';e++) set[e]=0; - goto match_set; - - case 'x': - for(e=0;e<256;e++) set[e]=1; - for(e='0';e<='9';e++) set[e]=0; - for(e='a';e<='f';e++) set[e]=0; - goto match_set; - - case 'D': - for(e=0;e<256;e++) set[e]=1; - for(e='0';e<='9';e++) set[e]=0; - set['-']=0; - set['x']=0; - goto match_set; - - case 'f': - for(e=0;e<256;e++) set[e]=1; - for(e='0';e<='9';e++) set[e]=0; - set['.']=set['-']=0; - goto match_set; - - case '[': /* oh dear */ - read_set(match,s-match+1,set,match_len); - for(e=0;e<256;e++) set[e]=!set[e]; - goto match_set; + /* sscanf("foo-bar","%s%d",a,b) might not work as expected */ + case 'd': + for(e=0;e<256;e++) set[e]=1; + for(e='0';e<='9';e++) set[e]=0; + set['-']=0; + goto match_set; + + case 'o': + for(e=0;e<256;e++) set[e]=1; + for(e='0';e<='7';e++) set[e]=0; + goto match_set; + + case 'x': + for(e=0;e<256;e++) set[e]=1; + for(e='0';e<='9';e++) set[e]=0; + for(e='a';e<='f';e++) set[e]=0; + goto match_set; + + case 'D': + for(e=0;e<256;e++) set[e]=1; + for(e='0';e<='9';e++) set[e]=0; + set['-']=0; + set['x']=0; + goto match_set; + + case 'f': + for(e=0;e<256;e++) set[e]=1; + for(e='0';e<='9';e++) set[e]=0; + set['.']=set['-']=0; + goto match_set; + + case '[': /* oh dear */ + read_set(match,s-match+1,set,match_len); + for(e=0;e<256;e++) set[e]=!set[e]; + goto match_set; + } } - } - contains_percent_percent=0; + contains_percent_percent=0; - for(e=cnt;e<match_len;e++) - { - if(match[e]=='%') + for(e=cnt;e<match_len;e++) { - if(match[e+1]=='%') + if(match[e]=='%') { - contains_percent_percent=1; - e++; - }else{ - break; + if(match[e+1]=='%') + { + contains_percent_percent=1; + e++; + }else{ + break; + } } } - } - end_str_end=match+e; + end_str_end=match+e; - if(!contains_percent_percent) - { - s=my_memmem(end_str_start, - end_str_end-end_str_start, - input+eye, - input_len-eye); - if(!s) return matches; - eye=s-input; - new_eye=eye+end_str_end-end_str_start; - }else{ - for(;eye<input_len;eye++) + if(!contains_percent_percent) { - p=input+eye; - for(s=end_str_start;s<end_str_end;s++,p++) + s=my_memmem(end_str_start, + end_str_end-end_str_start, + input+eye, + input_len-eye); + if(!s) return matches; + eye=s-input; + new_eye=eye+end_str_end-end_str_start; + }else{ + for(;eye<input_len;eye++) { - if(*s!=*p) break; - if(*s=='%') s++; + p=input+eye; + for(s=end_str_start;s<end_str_end;s++,p++) + { + if(*s!=*p) break; + if(*s=='%') s++; + } + if(s==end_str_end) + break; } - if(s==end_str_end) - break; + if(eye==input_len) + return matches; + new_eye=p-input; } - if(eye==input_len) - return matches; - new_eye=p-input; - } - sval.type=T_STRING; + sval.type=T_STRING; #ifdef __CHECKER__ - sval.subtype=0; + sval.subtype=0; #endif - sval.u.string=make_shared_binary_string(input+start,eye-start); + sval.u.string=make_shared_binary_string(input+start,eye-start); - cnt=end_str_end-match-1; - eye=new_eye; - break; - } + cnt=end_str_end-match-1; + eye=new_eye; + break; + } - case '[': - cnt=read_set(match,cnt+1,set,match_len); + case '[': + cnt=read_set(match,cnt+1,set,match_len); - match_set: - for(e=eye;eye<input_len && set[EXTRACT_UCHAR(input+eye)];eye++); - sval.type=T_STRING; + match_set: + for(e=eye;eye<input_len && set[EXTRACT_UCHAR(input+eye)];eye++); + sval.type=T_STRING; #ifdef __CHECKER__ - sval.subtype=0; + sval.subtype=0; #endif - sval.u.string=make_shared_binary_string(input+e,eye-e); - break; + sval.u.string=make_shared_binary_string(input+e,eye-e); + break; - case 'n': - sval.type=T_INT; - sval.subtype=NUMBER_NUMBER; - sval.u.integer=eye; - break; + case 'n': + sval.type=T_INT; + sval.subtype=NUMBER_NUMBER; + sval.u.integer=eye; + break; - default: - error("Unknown sscanf token %%%c\n",match[cnt]); + default: + error("Unknown sscanf token %%%c\n",match[cnt]); + } + break; } matches++;