Overview
SHA1 Hash: | 8c3ec00311d4641ac2bb9f9fd537cb4a7dd153f6 |
---|---|
Date: | 2008-02-04 19:07:58 |
User: | drh |
Comment: | On the printf extension converters (ex: %T, %w) the "alternate form flag" (ex: %#T, %#w) means first read an integer from the argument list and then only process that number of characters from the string or blob that is read next from the argument list. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/printf.c from [af38cba6b0] to [cefba92273].
@@ -148,10 +148,23 @@ ** Size of temporary conversion buffer. */ #define etBUFSIZE 500 /* +** Find the length of a string as long as that length does not +** exceed N bytes. If no zero terminator is seen in the first +** N bytes then return N. If N is negative, then this routine +** is an alias for strlen(). +*/ +static int strnlen(const char *z, int N){ + int n = 0; + while( (N-- != 0) && *(z++)!=0 ){ n++; } + return n; +} + + +/* ** The root program. All variations call this core. ** ** INPUTS: ** func This is a pointer to a function taking three arguments ** 1. A pointer to anything. Same as the "arg" parameter. @@ -547,13 +560,14 @@ } bufpt = buf; break; case etPATH: { int i; + int limit = flag_alternateform ? va_arg(ap,int) : -1; char *e = va_arg(ap,char*); if( e==0 ){e="";} - length = strlen(e); + length = strnlen(e, limit); zExtra = bufpt = malloc(length+1); for( i=0; i<length; i++ ){ if( e[i]=='\\' ){ bufpt[i]='/'; }else{ @@ -562,31 +576,37 @@ } bufpt[length]='\0'; break; } case etSTRING: - case etDYNSTRING: + case etDYNSTRING: { + int limit = flag_alternateform ? va_arg(ap,int) : -1; bufpt = va_arg(ap,char*); if( bufpt==0 ){ bufpt = ""; }else if( xtype==etDYNSTRING ){ zExtra = bufpt; } - length = strlen(bufpt); + length = strnlen(bufpt, limit); if( precision>=0 && precision<length ) length = precision; break; + } case etBLOB: { + int limit = flag_alternateform ? va_arg(ap, int) : -1; Blob *pBlob = va_arg(ap, Blob*); bufpt = blob_buffer(pBlob); length = blob_size(pBlob); + if( limit>=0 && limit<length ) length = limit; break; } case etBLOBSQL: { + int limit = flag_alternateform ? va_arg(ap, int) : -1; Blob *pBlob = va_arg(ap, Blob*); char *zOrig = blob_buffer(pBlob); int i, j, n, cnt; n = blob_size(pBlob); + if( limit>=0 && limit<n ) n = limit; for(cnt=i=0; i<n; i++){ if( zOrig[i]=='\'' ) cnt++; } if( n+cnt+2 > etBUFSIZE ){ bufpt = zExtra = malloc( n + cnt + 2 ); }else{ bufpt = buf; @@ -603,15 +623,17 @@ } case etSQLESCAPE: case etSQLESCAPE2: { int i, j, n, ch, isnull; int needQuote; + int limit = flag_alternateform ? va_arg(ap,int) : -1; char *escarg = va_arg(ap,char*); isnull = escarg==0; if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); - for(i=n=0; (ch=escarg[i])!=0; i++){ - if( ch=='\'' ) n++; + if( limit<0 ) limit = strlen(escarg); + for(i=n=0; i<limit; i++){ + if( escarg[i]=='\'' ) n++; } needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ bufpt = zExtra = malloc( n ); @@ -619,56 +641,61 @@ }else{ bufpt = buf; } j = 0; if( needQuote ) bufpt[j++] = '\''; - for(i=0; (ch=escarg[i])!=0; i++){ - bufpt[j++] = ch; + for(i=0; i<limit; i++){ + bufpt[j++] = ch = escarg[i]; if( ch=='\'' ) bufpt[j++] = ch; } if( needQuote ) bufpt[j++] = '\''; bufpt[j] = 0; length = j; if( precision>=0 && precision<length ) length = precision; break; } case etHTMLIZE: { + int limit = flag_alternateform ? va_arg(ap,int) : -1; char *zMem = va_arg(ap,char*); if( zMem==0 ) zMem = ""; - zExtra = bufpt = htmlize(zMem, -1); + zExtra = bufpt = htmlize(zMem, limit); length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; } case etHTTPIZE: { + int limit = flag_alternateform ? va_arg(ap,int) : -1; char *zMem = va_arg(ap,char*); if( zMem==0 ) zMem = ""; - zExtra = bufpt = httpize(zMem, -1); + zExtra = bufpt = httpize(zMem, limit); length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; } case etURLIZE: { + int limit = flag_alternateform ? va_arg(ap,int) : -1; char *zMem = va_arg(ap,char*); if( zMem==0 ) zMem = ""; - zExtra = bufpt = urlize(zMem, -1); + zExtra = bufpt = urlize(zMem, limit); length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; } case etFOSSILIZE: { + int limit = flag_alternateform ? va_arg(ap,int) : -1; char *zMem = va_arg(ap,char*); if( zMem==0 ) zMem = ""; - zExtra = bufpt = fossilize(zMem, -1); + zExtra = bufpt = fossilize(zMem, limit); length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; } case etWIKISTR: { + int limit = flag_alternateform ? va_arg(ap,int) : -1; char *zWiki = va_arg(ap, char*); Blob wiki; - blob_init(&wiki, zWiki, -1); + blob_init(&wiki, zWiki, limit); wiki_convert(&wiki, pBlob, WIKI_INLINE); blob_reset(&wiki); length = width = 0; break; }