Fossil SCM

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.

drh 2008-02-04 19:07 trunk
Commit 8c3ec00311d4641ac2bb9f9fd537cb4a7dd153f6
1 file changed +39 -12
+39 -12
--- src/printf.c
+++ src/printf.c
@@ -146,10 +146,23 @@
146146
147147
/*
148148
** Size of temporary conversion buffer.
149149
*/
150150
#define etBUFSIZE 500
151
+
152
+/*
153
+** Find the length of a string as long as that length does not
154
+** exceed N bytes. If no zero terminator is seen in the first
155
+** N bytes then return N. If N is negative, then this routine
156
+** is an alias for strlen().
157
+*/
158
+static int strnlen(const char *z, int N){
159
+ int n = 0;
160
+ while( (N-- != 0) && *(z++)!=0 ){ n++; }
161
+ return n;
162
+}
163
+
151164
152165
/*
153166
** The root program. All variations call this core.
154167
**
155168
** INPUTS:
@@ -547,13 +560,14 @@
547560
}
548561
bufpt = buf;
549562
break;
550563
case etPATH: {
551564
int i;
565
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
552566
char *e = va_arg(ap,char*);
553567
if( e==0 ){e="";}
554
- length = strlen(e);
568
+ length = strnlen(e, limit);
555569
zExtra = bufpt = malloc(length+1);
556570
for( i=0; i<length; i++ ){
557571
if( e[i]=='\\' ){
558572
bufpt[i]='/';
559573
}else{
@@ -562,31 +576,37 @@
562576
}
563577
bufpt[length]='\0';
564578
break;
565579
}
566580
case etSTRING:
567
- case etDYNSTRING:
581
+ case etDYNSTRING: {
582
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
568583
bufpt = va_arg(ap,char*);
569584
if( bufpt==0 ){
570585
bufpt = "";
571586
}else if( xtype==etDYNSTRING ){
572587
zExtra = bufpt;
573588
}
574
- length = strlen(bufpt);
589
+ length = strnlen(bufpt, limit);
575590
if( precision>=0 && precision<length ) length = precision;
576591
break;
592
+ }
577593
case etBLOB: {
594
+ int limit = flag_alternateform ? va_arg(ap, int) : -1;
578595
Blob *pBlob = va_arg(ap, Blob*);
579596
bufpt = blob_buffer(pBlob);
580597
length = blob_size(pBlob);
598
+ if( limit>=0 && limit<length ) length = limit;
581599
break;
582600
}
583601
case etBLOBSQL: {
602
+ int limit = flag_alternateform ? va_arg(ap, int) : -1;
584603
Blob *pBlob = va_arg(ap, Blob*);
585604
char *zOrig = blob_buffer(pBlob);
586605
int i, j, n, cnt;
587606
n = blob_size(pBlob);
607
+ if( limit>=0 && limit<n ) n = limit;
588608
for(cnt=i=0; i<n; i++){ if( zOrig[i]=='\'' ) cnt++; }
589609
if( n+cnt+2 > etBUFSIZE ){
590610
bufpt = zExtra = malloc( n + cnt + 2 );
591611
}else{
592612
bufpt = buf;
@@ -603,15 +623,17 @@
603623
}
604624
case etSQLESCAPE:
605625
case etSQLESCAPE2: {
606626
int i, j, n, ch, isnull;
607627
int needQuote;
628
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
608629
char *escarg = va_arg(ap,char*);
609630
isnull = escarg==0;
610631
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
611
- for(i=n=0; (ch=escarg[i])!=0; i++){
612
- if( ch=='\'' ) n++;
632
+ if( limit<0 ) limit = strlen(escarg);
633
+ for(i=n=0; i<limit; i++){
634
+ if( escarg[i]=='\'' ) n++;
613635
}
614636
needQuote = !isnull && xtype==etSQLESCAPE2;
615637
n += i + 1 + needQuote*2;
616638
if( n>etBUFSIZE ){
617639
bufpt = zExtra = malloc( n );
@@ -619,56 +641,61 @@
619641
}else{
620642
bufpt = buf;
621643
}
622644
j = 0;
623645
if( needQuote ) bufpt[j++] = '\'';
624
- for(i=0; (ch=escarg[i])!=0; i++){
625
- bufpt[j++] = ch;
646
+ for(i=0; i<limit; i++){
647
+ bufpt[j++] = ch = escarg[i];
626648
if( ch=='\'' ) bufpt[j++] = ch;
627649
}
628650
if( needQuote ) bufpt[j++] = '\'';
629651
bufpt[j] = 0;
630652
length = j;
631653
if( precision>=0 && precision<length ) length = precision;
632654
break;
633655
}
634656
case etHTMLIZE: {
657
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
635658
char *zMem = va_arg(ap,char*);
636659
if( zMem==0 ) zMem = "";
637
- zExtra = bufpt = htmlize(zMem, -1);
660
+ zExtra = bufpt = htmlize(zMem, limit);
638661
length = strlen(bufpt);
639662
if( precision>=0 && precision<length ) length = precision;
640663
break;
641664
}
642665
case etHTTPIZE: {
666
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
643667
char *zMem = va_arg(ap,char*);
644668
if( zMem==0 ) zMem = "";
645
- zExtra = bufpt = httpize(zMem, -1);
669
+ zExtra = bufpt = httpize(zMem, limit);
646670
length = strlen(bufpt);
647671
if( precision>=0 && precision<length ) length = precision;
648672
break;
649673
}
650674
case etURLIZE: {
675
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
651676
char *zMem = va_arg(ap,char*);
652677
if( zMem==0 ) zMem = "";
653
- zExtra = bufpt = urlize(zMem, -1);
678
+ zExtra = bufpt = urlize(zMem, limit);
654679
length = strlen(bufpt);
655680
if( precision>=0 && precision<length ) length = precision;
656681
break;
657682
}
658683
case etFOSSILIZE: {
684
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
659685
char *zMem = va_arg(ap,char*);
660686
if( zMem==0 ) zMem = "";
661
- zExtra = bufpt = fossilize(zMem, -1);
687
+ zExtra = bufpt = fossilize(zMem, limit);
662688
length = strlen(bufpt);
663689
if( precision>=0 && precision<length ) length = precision;
664690
break;
665691
}
666692
case etWIKISTR: {
693
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
667694
char *zWiki = va_arg(ap, char*);
668695
Blob wiki;
669
- blob_init(&wiki, zWiki, -1);
696
+ blob_init(&wiki, zWiki, limit);
670697
wiki_convert(&wiki, pBlob, WIKI_INLINE);
671698
blob_reset(&wiki);
672699
length = width = 0;
673700
break;
674701
}
675702
--- src/printf.c
+++ src/printf.c
@@ -146,10 +146,23 @@
146
147 /*
148 ** Size of temporary conversion buffer.
149 */
150 #define etBUFSIZE 500
 
 
 
 
 
 
 
 
 
 
 
 
 
151
152 /*
153 ** The root program. All variations call this core.
154 **
155 ** INPUTS:
@@ -547,13 +560,14 @@
547 }
548 bufpt = buf;
549 break;
550 case etPATH: {
551 int i;
 
552 char *e = va_arg(ap,char*);
553 if( e==0 ){e="";}
554 length = strlen(e);
555 zExtra = bufpt = malloc(length+1);
556 for( i=0; i<length; i++ ){
557 if( e[i]=='\\' ){
558 bufpt[i]='/';
559 }else{
@@ -562,31 +576,37 @@
562 }
563 bufpt[length]='\0';
564 break;
565 }
566 case etSTRING:
567 case etDYNSTRING:
 
568 bufpt = va_arg(ap,char*);
569 if( bufpt==0 ){
570 bufpt = "";
571 }else if( xtype==etDYNSTRING ){
572 zExtra = bufpt;
573 }
574 length = strlen(bufpt);
575 if( precision>=0 && precision<length ) length = precision;
576 break;
 
577 case etBLOB: {
 
578 Blob *pBlob = va_arg(ap, Blob*);
579 bufpt = blob_buffer(pBlob);
580 length = blob_size(pBlob);
 
581 break;
582 }
583 case etBLOBSQL: {
 
584 Blob *pBlob = va_arg(ap, Blob*);
585 char *zOrig = blob_buffer(pBlob);
586 int i, j, n, cnt;
587 n = blob_size(pBlob);
 
588 for(cnt=i=0; i<n; i++){ if( zOrig[i]=='\'' ) cnt++; }
589 if( n+cnt+2 > etBUFSIZE ){
590 bufpt = zExtra = malloc( n + cnt + 2 );
591 }else{
592 bufpt = buf;
@@ -603,15 +623,17 @@
603 }
604 case etSQLESCAPE:
605 case etSQLESCAPE2: {
606 int i, j, n, ch, isnull;
607 int needQuote;
 
608 char *escarg = va_arg(ap,char*);
609 isnull = escarg==0;
610 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
611 for(i=n=0; (ch=escarg[i])!=0; i++){
612 if( ch=='\'' ) n++;
 
613 }
614 needQuote = !isnull && xtype==etSQLESCAPE2;
615 n += i + 1 + needQuote*2;
616 if( n>etBUFSIZE ){
617 bufpt = zExtra = malloc( n );
@@ -619,56 +641,61 @@
619 }else{
620 bufpt = buf;
621 }
622 j = 0;
623 if( needQuote ) bufpt[j++] = '\'';
624 for(i=0; (ch=escarg[i])!=0; i++){
625 bufpt[j++] = ch;
626 if( ch=='\'' ) bufpt[j++] = ch;
627 }
628 if( needQuote ) bufpt[j++] = '\'';
629 bufpt[j] = 0;
630 length = j;
631 if( precision>=0 && precision<length ) length = precision;
632 break;
633 }
634 case etHTMLIZE: {
 
635 char *zMem = va_arg(ap,char*);
636 if( zMem==0 ) zMem = "";
637 zExtra = bufpt = htmlize(zMem, -1);
638 length = strlen(bufpt);
639 if( precision>=0 && precision<length ) length = precision;
640 break;
641 }
642 case etHTTPIZE: {
 
643 char *zMem = va_arg(ap,char*);
644 if( zMem==0 ) zMem = "";
645 zExtra = bufpt = httpize(zMem, -1);
646 length = strlen(bufpt);
647 if( precision>=0 && precision<length ) length = precision;
648 break;
649 }
650 case etURLIZE: {
 
651 char *zMem = va_arg(ap,char*);
652 if( zMem==0 ) zMem = "";
653 zExtra = bufpt = urlize(zMem, -1);
654 length = strlen(bufpt);
655 if( precision>=0 && precision<length ) length = precision;
656 break;
657 }
658 case etFOSSILIZE: {
 
659 char *zMem = va_arg(ap,char*);
660 if( zMem==0 ) zMem = "";
661 zExtra = bufpt = fossilize(zMem, -1);
662 length = strlen(bufpt);
663 if( precision>=0 && precision<length ) length = precision;
664 break;
665 }
666 case etWIKISTR: {
 
667 char *zWiki = va_arg(ap, char*);
668 Blob wiki;
669 blob_init(&wiki, zWiki, -1);
670 wiki_convert(&wiki, pBlob, WIKI_INLINE);
671 blob_reset(&wiki);
672 length = width = 0;
673 break;
674 }
675
--- src/printf.c
+++ src/printf.c
@@ -146,10 +146,23 @@
146
147 /*
148 ** Size of temporary conversion buffer.
149 */
150 #define etBUFSIZE 500
151
152 /*
153 ** Find the length of a string as long as that length does not
154 ** exceed N bytes. If no zero terminator is seen in the first
155 ** N bytes then return N. If N is negative, then this routine
156 ** is an alias for strlen().
157 */
158 static int strnlen(const char *z, int N){
159 int n = 0;
160 while( (N-- != 0) && *(z++)!=0 ){ n++; }
161 return n;
162 }
163
164
165 /*
166 ** The root program. All variations call this core.
167 **
168 ** INPUTS:
@@ -547,13 +560,14 @@
560 }
561 bufpt = buf;
562 break;
563 case etPATH: {
564 int i;
565 int limit = flag_alternateform ? va_arg(ap,int) : -1;
566 char *e = va_arg(ap,char*);
567 if( e==0 ){e="";}
568 length = strnlen(e, limit);
569 zExtra = bufpt = malloc(length+1);
570 for( i=0; i<length; i++ ){
571 if( e[i]=='\\' ){
572 bufpt[i]='/';
573 }else{
@@ -562,31 +576,37 @@
576 }
577 bufpt[length]='\0';
578 break;
579 }
580 case etSTRING:
581 case etDYNSTRING: {
582 int limit = flag_alternateform ? va_arg(ap,int) : -1;
583 bufpt = va_arg(ap,char*);
584 if( bufpt==0 ){
585 bufpt = "";
586 }else if( xtype==etDYNSTRING ){
587 zExtra = bufpt;
588 }
589 length = strnlen(bufpt, limit);
590 if( precision>=0 && precision<length ) length = precision;
591 break;
592 }
593 case etBLOB: {
594 int limit = flag_alternateform ? va_arg(ap, int) : -1;
595 Blob *pBlob = va_arg(ap, Blob*);
596 bufpt = blob_buffer(pBlob);
597 length = blob_size(pBlob);
598 if( limit>=0 && limit<length ) length = limit;
599 break;
600 }
601 case etBLOBSQL: {
602 int limit = flag_alternateform ? va_arg(ap, int) : -1;
603 Blob *pBlob = va_arg(ap, Blob*);
604 char *zOrig = blob_buffer(pBlob);
605 int i, j, n, cnt;
606 n = blob_size(pBlob);
607 if( limit>=0 && limit<n ) n = limit;
608 for(cnt=i=0; i<n; i++){ if( zOrig[i]=='\'' ) cnt++; }
609 if( n+cnt+2 > etBUFSIZE ){
610 bufpt = zExtra = malloc( n + cnt + 2 );
611 }else{
612 bufpt = buf;
@@ -603,15 +623,17 @@
623 }
624 case etSQLESCAPE:
625 case etSQLESCAPE2: {
626 int i, j, n, ch, isnull;
627 int needQuote;
628 int limit = flag_alternateform ? va_arg(ap,int) : -1;
629 char *escarg = va_arg(ap,char*);
630 isnull = escarg==0;
631 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
632 if( limit<0 ) limit = strlen(escarg);
633 for(i=n=0; i<limit; i++){
634 if( escarg[i]=='\'' ) n++;
635 }
636 needQuote = !isnull && xtype==etSQLESCAPE2;
637 n += i + 1 + needQuote*2;
638 if( n>etBUFSIZE ){
639 bufpt = zExtra = malloc( n );
@@ -619,56 +641,61 @@
641 }else{
642 bufpt = buf;
643 }
644 j = 0;
645 if( needQuote ) bufpt[j++] = '\'';
646 for(i=0; i<limit; i++){
647 bufpt[j++] = ch = escarg[i];
648 if( ch=='\'' ) bufpt[j++] = ch;
649 }
650 if( needQuote ) bufpt[j++] = '\'';
651 bufpt[j] = 0;
652 length = j;
653 if( precision>=0 && precision<length ) length = precision;
654 break;
655 }
656 case etHTMLIZE: {
657 int limit = flag_alternateform ? va_arg(ap,int) : -1;
658 char *zMem = va_arg(ap,char*);
659 if( zMem==0 ) zMem = "";
660 zExtra = bufpt = htmlize(zMem, limit);
661 length = strlen(bufpt);
662 if( precision>=0 && precision<length ) length = precision;
663 break;
664 }
665 case etHTTPIZE: {
666 int limit = flag_alternateform ? va_arg(ap,int) : -1;
667 char *zMem = va_arg(ap,char*);
668 if( zMem==0 ) zMem = "";
669 zExtra = bufpt = httpize(zMem, limit);
670 length = strlen(bufpt);
671 if( precision>=0 && precision<length ) length = precision;
672 break;
673 }
674 case etURLIZE: {
675 int limit = flag_alternateform ? va_arg(ap,int) : -1;
676 char *zMem = va_arg(ap,char*);
677 if( zMem==0 ) zMem = "";
678 zExtra = bufpt = urlize(zMem, limit);
679 length = strlen(bufpt);
680 if( precision>=0 && precision<length ) length = precision;
681 break;
682 }
683 case etFOSSILIZE: {
684 int limit = flag_alternateform ? va_arg(ap,int) : -1;
685 char *zMem = va_arg(ap,char*);
686 if( zMem==0 ) zMem = "";
687 zExtra = bufpt = fossilize(zMem, limit);
688 length = strlen(bufpt);
689 if( precision>=0 && precision<length ) length = precision;
690 break;
691 }
692 case etWIKISTR: {
693 int limit = flag_alternateform ? va_arg(ap,int) : -1;
694 char *zWiki = va_arg(ap, char*);
695 Blob wiki;
696 blob_init(&wiki, zWiki, limit);
697 wiki_convert(&wiki, pBlob, WIKI_INLINE);
698 blob_reset(&wiki);
699 length = width = 0;
700 break;
701 }
702

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button