/ Check-in [40d8f8ae]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Performance improvement in the parsing of options to %-formats in the printf implementation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 40d8f8ae87abf928542c4e558a4c3a3eab18776a3e8db7ca1c5e5f744ca0bce3
User & Date: drh 2019-02-01 18:46:41
Context
2019-02-01
20:29
Prevent the printf formatter from doing large memory allocations - larger than either the size of the static buffer for interfaces like sqlite3_snprintf(), or larger than SQLITE_LIMIT_LENGTH for interfaces that are associated with a database connection. This helps to prevent DOS attacks on products that let hostile sources inject arbitrary SQL. It also helps fuzzers run faster and more effectively. check-in: 179e5d46 user: drh tags: trunk
18:46
Performance improvement in the parsing of options to %-formats in the printf implementation. check-in: 40d8f8ae user: drh tags: trunk
15:06
Ensure that the Walker.pParse structure is initialized when walking the source tree to gather the WINDOW clauses on a query with window functions. check-in: 4ca9d5d5 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/printf.c.

   233    233         sqlite3_str_append(pAccum, "%", 1);
   234    234         break;
   235    235       }
   236    236       /* Find out what flags are present */
   237    237       flag_leftjustify = flag_prefix = cThousand =
   238    238        flag_alternateform = flag_altform2 = flag_zeropad = 0;
   239    239       done = 0;
          240  +    width = 0;
          241  +    flag_long = 0;
          242  +    precision = -1;
   240    243       do{
   241    244         switch( c ){
   242    245           case '-':   flag_leftjustify = 1;     break;
   243    246           case '+':   flag_prefix = '+';        break;
   244    247           case ' ':   flag_prefix = ' ';        break;
   245    248           case '#':   flag_alternateform = 1;   break;
   246    249           case '!':   flag_altform2 = 1;        break;
   247    250           case '0':   flag_zeropad = 1;         break;
   248    251           case ',':   cThousand = ',';          break;
   249    252           default:    done = 1;                 break;
          253  +        case 'l': {
          254  +          flag_long = 1;
          255  +          c = *++fmt;
          256  +          if( c=='l' ){
          257  +            c = *++fmt;
          258  +            flag_long = 2;
          259  +          }
          260  +          done = 1;
          261  +          break;
          262  +        }
          263  +        case '1': case '2': case '3': case '4': case '5':
          264  +        case '6': case '7': case '8': case '9': {
          265  +          unsigned wx = c - '0';
          266  +          while( (c = *++fmt)>='0' && c<='9' ){
          267  +            wx = wx*10 + c - '0';
          268  +          }
          269  +          testcase( wx>0x7fffffff );
          270  +          width = wx & 0x7fffffff;
          271  +#ifdef SQLITE_PRINTF_PRECISION_LIMIT
          272  +          if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
          273  +            width = SQLITE_PRINTF_PRECISION_LIMIT;
          274  +          }
          275  +#endif
          276  +          if( c!='.' && c!='l' ){
          277  +            done = 1;
          278  +          }else{
          279  +            fmt--;
          280  +          }
          281  +          break;
          282  +        }
          283  +        case '*': {
          284  +          if( bArgList ){
          285  +            width = (int)getIntArg(pArgList);
          286  +          }else{
          287  +            width = va_arg(ap,int);
          288  +          }
          289  +          if( width<0 ){
          290  +            flag_leftjustify = 1;
          291  +            width = width >= -2147483647 ? -width : 0;
          292  +          }
          293  +#ifdef SQLITE_PRINTF_PRECISION_LIMIT
          294  +          if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
          295  +            width = SQLITE_PRINTF_PRECISION_LIMIT;
          296  +          }
          297  +#endif
          298  +          if( (c = fmt[1])!='.' && c!='l' ){
          299  +            c = *++fmt;
          300  +            done = 1;
          301  +          }
          302  +          break;
          303  +        }
          304  +        case '.': {
          305  +          c = *++fmt;
          306  +          if( c=='*' ){
          307  +            if( bArgList ){
          308  +              precision = (int)getIntArg(pArgList);
          309  +            }else{
          310  +              precision = va_arg(ap,int);
          311  +            }
          312  +            if( precision<0 ){
          313  +              precision = precision >= -2147483647 ? -precision : -1;
          314  +            }
          315  +            c = *++fmt;
          316  +          }else{
          317  +            unsigned px = 0;
          318  +            while( c>='0' && c<='9' ){
          319  +              px = px*10 + c - '0';
          320  +              c = *++fmt;
          321  +            }
          322  +            testcase( px>0x7fffffff );
          323  +            precision = px & 0x7fffffff;
          324  +          }
          325  +#ifdef SQLITE_PRINTF_PRECISION_LIMIT
          326  +          if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
          327  +            precision = SQLITE_PRINTF_PRECISION_LIMIT;
          328  +          }
          329  +#endif
          330  +          if( c=='l' ){
          331  +            --fmt;
          332  +          }else{
          333  +            done = 1;
          334  +          }
          335  +          break;
          336  +        }
   250    337         }
   251    338       }while( !done && (c=(*++fmt))!=0 );
   252         -    /* Get the field width */
   253         -    if( c=='*' ){
   254         -      if( bArgList ){
   255         -        width = (int)getIntArg(pArgList);
   256         -      }else{
   257         -        width = va_arg(ap,int);
   258         -      }
   259         -      if( width<0 ){
   260         -        flag_leftjustify = 1;
   261         -        width = width >= -2147483647 ? -width : 0;
   262         -      }
   263         -      c = *++fmt;
   264         -    }else{
   265         -      unsigned wx = 0;
   266         -      while( c>='0' && c<='9' ){
   267         -        wx = wx*10 + c - '0';
   268         -        c = *++fmt;
   269         -      }
   270         -      testcase( wx>0x7fffffff );
   271         -      width = wx & 0x7fffffff;
   272         -    }
   273         -    assert( width>=0 );
   274         -#ifdef SQLITE_PRINTF_PRECISION_LIMIT
   275         -    if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
   276         -      width = SQLITE_PRINTF_PRECISION_LIMIT;
   277         -    }
   278         -#endif
   279    339   
   280         -    /* Get the precision */
   281         -    if( c=='.' ){
   282         -      c = *++fmt;
   283         -      if( c=='*' ){
   284         -        if( bArgList ){
   285         -          precision = (int)getIntArg(pArgList);
   286         -        }else{
   287         -          precision = va_arg(ap,int);
   288         -        }
   289         -        c = *++fmt;
   290         -        if( precision<0 ){
   291         -          precision = precision >= -2147483647 ? -precision : -1;
   292         -        }
   293         -      }else{
   294         -        unsigned px = 0;
   295         -        while( c>='0' && c<='9' ){
   296         -          px = px*10 + c - '0';
   297         -          c = *++fmt;
   298         -        }
   299         -        testcase( px>0x7fffffff );
   300         -        precision = px & 0x7fffffff;
   301         -      }
   302         -    }else{
   303         -      precision = -1;
   304         -    }
   305         -    assert( precision>=(-1) );
   306         -#ifdef SQLITE_PRINTF_PRECISION_LIMIT
   307         -    if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
   308         -      precision = SQLITE_PRINTF_PRECISION_LIMIT;
   309         -    }
   310         -#endif
   311         -
   312         -
   313         -    /* Get the conversion type modifier */
   314         -    if( c=='l' ){
   315         -      flag_long = 1;
   316         -      c = *++fmt;
   317         -      if( c=='l' ){
   318         -        flag_long = 2;
   319         -        c = *++fmt;
   320         -      }
   321         -    }else{
   322         -      flag_long = 0;
   323         -    }
   324    340       /* Fetch the info entry for the field */
   325    341       infop = &fmtinfo[0];
   326    342       xtype = etINVALID;
   327    343       for(idx=0; idx<ArraySize(fmtinfo); idx++){
   328    344         if( c==fmtinfo[idx].fmttype ){
   329    345           infop = &fmtinfo[idx];
   330    346           xtype = infop->type;