Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit888271e

Browse files
committed
Fix snprintf to handle %$ properly by storing and reordering the
arguments.Nicolai Tufar
1 parent83e87e6 commit888271e

File tree

1 file changed

+103
-97
lines changed

1 file changed

+103
-97
lines changed

‎src/port/snprintf.c

Lines changed: 103 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
* causing nasty effects.
6666
**************************************************************/
6767

68-
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.19 2005/03/12 04:00:56 momjian Exp $";*/
68+
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.20 2005/03/16 06:00:58 momjian Exp $";*/
6969

7070
intpg_snprintf(char*str,size_tcount,constchar*fmt,...);
7171
intpg_vsnprintf(char*str,size_tcount,constchar*fmt,va_listargs);
@@ -151,20 +151,20 @@ static void dopr_outch(int c, char *end, char **output);
151151

152152
#defineFMTSTR1
153153
#defineFMTNUM2
154-
#defineFMTFLOAT3
155-
#defineFMTCHAR4
154+
#defineFMTNUM_U3
155+
#defineFMTFLOAT4
156+
#defineFMTCHAR5
157+
#defineFMTWIDTH6
158+
#defineFMTLEN7
156159

157160
staticvoid
158161
dopr(char*buffer,constchar*format,va_listargs,char*end)
159162
{
160163
intch;
161-
int64value;
162-
doublefvalue;
163164
intlonglongflag=0;
164165
intlongflag=0;
165166
intpointflag=0;
166167
intmaxwidth=0;
167-
char*strvalue;
168168
intljust;
169169
intlen;
170170
intzpad;
@@ -173,6 +173,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
173173
constchar*fmtbegin;
174174
intfmtpos=1;
175175
intrealpos=0;
176+
intprecision;
176177
intposition;
177178
char*output;
178179
intpercents=1;
@@ -195,6 +196,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
195196
intpointflag;
196197
charfunc;
197198
intrealpos;
199+
intlongflag;
200+
intlonglongflag;
198201
}*fmtpar,**fmtparptr;
199202

200203
/* Create enough structures to hold all arguments */
@@ -229,12 +232,12 @@ dopr(char *buffer, const char *format, va_list args, char *end)
229232
longflag=longlongflag=pointflag=0;
230233
fmtbegin=format-1;
231234
realpos=0;
232-
position=0;
235+
position=precision=0;
233236
nextch:
234237
ch=*format++;
235238
switch (ch)
236239
{
237-
case0:
240+
case'\0':
238241
gotoperformpr;
239242
case'-':
240243
ljust=1;
@@ -251,24 +254,29 @@ dopr(char *buffer, const char *format, va_list args, char *end)
251254
case'7':
252255
case'8':
253256
case'9':
254-
if (pointflag)
255-
/* could also be precision */
256-
maxwidth=maxwidth*10+ch-'0';
257-
else
257+
if (!pointflag)
258258
{
259259
len=len*10+ch-'0';
260260
position=position*10+ch-'0';
261261
}
262+
else
263+
{
264+
maxwidth=maxwidth*10+ch-'0';
265+
precision=precision*10+ch-'0';
266+
}
262267
gotonextch;
263268
case'$':
264269
realpos=position;
265270
len=0;
266271
gotonextch;
267272
case'*':
268-
if (pointflag)
269-
maxwidth=va_arg(args,int);
273+
MemSet(&fmtpar[fmtpos],0,sizeof(fmtpar[fmtpos]));
274+
if (!pointflag)
275+
fmtpar[fmtpos].func=FMTLEN;
270276
else
271-
len=va_arg(args,int);
277+
fmtpar[fmtpos].func=FMTWIDTH;
278+
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
279+
fmtpos++;
272280
gotonextch;
273281
case'.':
274282
pointflag=1;
@@ -301,68 +309,40 @@ dopr(char *buffer, const char *format, va_list args, char *end)
301309
#endif
302310
case'u':
303311
case'U':
304-
/* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
305-
if (longflag)
306-
{
307-
if (longlongflag)
308-
value=va_arg(args,uint64);
309-
else
310-
value=va_arg(args,unsignedlong);
311-
}
312-
else
313-
value=va_arg(args,unsignedint);
312+
fmtpar[fmtpos].longflag=longflag;
313+
fmtpar[fmtpos].longlongflag=longlongflag;
314314
fmtpar[fmtpos].fmtbegin=fmtbegin;
315315
fmtpar[fmtpos].fmtend=format;
316-
fmtpar[fmtpos].numvalue=value;
317316
fmtpar[fmtpos].base=10;
318317
fmtpar[fmtpos].dosign=0;
319318
fmtpar[fmtpos].ljust=ljust;
320319
fmtpar[fmtpos].len=len;
321320
fmtpar[fmtpos].zpad=zpad;
322-
fmtpar[fmtpos].func=FMTNUM;
321+
fmtpar[fmtpos].func=FMTNUM_U;
323322
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
324323
fmtpos++;
325324
break;
326325
case'o':
327326
case'O':
328-
/* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
329-
if (longflag)
330-
{
331-
if (longlongflag)
332-
value=va_arg(args,uint64);
333-
else
334-
value=va_arg(args,unsignedlong);
335-
}
336-
else
337-
value=va_arg(args,unsignedint);
327+
fmtpar[fmtpos].longflag=longflag;
328+
fmtpar[fmtpos].longlongflag=longlongflag;
338329
fmtpar[fmtpos].fmtbegin=fmtbegin;
339330
fmtpar[fmtpos].fmtend=format;
340-
fmtpar[fmtpos].numvalue=value;
341331
fmtpar[fmtpos].base=8;
342332
fmtpar[fmtpos].dosign=0;
343333
fmtpar[fmtpos].ljust=ljust;
344334
fmtpar[fmtpos].len=len;
345335
fmtpar[fmtpos].zpad=zpad;
346-
fmtpar[fmtpos].func=FMTNUM;
336+
fmtpar[fmtpos].func=FMTNUM_U;
347337
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
348338
fmtpos++;
349339
break;
350340
case'd':
351341
case'D':
352-
if (longflag)
353-
{
354-
if (longlongflag)
355-
{
356-
value=va_arg(args,int64);
357-
}
358-
else
359-
value=va_arg(args,long);
360-
}
361-
else
362-
value=va_arg(args,int);
342+
fmtpar[fmtpos].longflag=longflag;
343+
fmtpar[fmtpos].longlongflag=longlongflag;
363344
fmtpar[fmtpos].fmtbegin=fmtbegin;
364345
fmtpar[fmtpos].fmtend=format;
365-
fmtpar[fmtpos].numvalue=value;
366346
fmtpar[fmtpos].base=10;
367347
fmtpar[fmtpos].dosign=1;
368348
fmtpar[fmtpos].ljust=ljust;
@@ -373,72 +353,47 @@ dopr(char *buffer, const char *format, va_list args, char *end)
373353
fmtpos++;
374354
break;
375355
case'x':
376-
if (longflag)
377-
{
378-
if (longlongflag)
379-
value=va_arg(args,uint64);
380-
else
381-
value=va_arg(args,unsignedlong);
382-
}
383-
else
384-
value=va_arg(args,unsignedint);
356+
fmtpar[fmtpos].longflag=longflag;
357+
fmtpar[fmtpos].longlongflag=longlongflag;
385358
fmtpar[fmtpos].fmtbegin=fmtbegin;
386359
fmtpar[fmtpos].fmtend=format;
387-
fmtpar[fmtpos].numvalue=value;
388360
fmtpar[fmtpos].base=16;
389361
fmtpar[fmtpos].dosign=0;
390362
fmtpar[fmtpos].ljust=ljust;
391363
fmtpar[fmtpos].len=len;
392364
fmtpar[fmtpos].zpad=zpad;
393-
fmtpar[fmtpos].func=FMTNUM;
365+
fmtpar[fmtpos].func=FMTNUM_U;
394366
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
395367
fmtpos++;
396368
break;
397369
case'X':
398-
if (longflag)
399-
{
400-
if (longlongflag)
401-
value=va_arg(args,uint64);
402-
else
403-
value=va_arg(args,unsignedlong);
404-
}
405-
else
406-
value=va_arg(args,unsignedint);
370+
fmtpar[fmtpos].longflag=longflag;
371+
fmtpar[fmtpos].longlongflag=longlongflag;
407372
fmtpar[fmtpos].fmtbegin=fmtbegin;
408373
fmtpar[fmtpos].fmtend=format;
409-
fmtpar[fmtpos].numvalue=value;
410374
fmtpar[fmtpos].base=-16;
411375
fmtpar[fmtpos].dosign=1;
412376
fmtpar[fmtpos].ljust=ljust;
413377
fmtpar[fmtpos].len=len;
414378
fmtpar[fmtpos].zpad=zpad;
415-
fmtpar[fmtpos].func=FMTNUM;
379+
fmtpar[fmtpos].func=FMTNUM_U;
416380
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
417381
fmtpos++;
418382
break;
419383
case's':
420-
strvalue=va_arg(args,char*);
421-
if (maxwidth>0|| !pointflag)
422-
{
423-
if (pointflag&&len>maxwidth)
424-
len=maxwidth;/* Adjust padding */
425-
fmtpar[fmtpos].fmtbegin=fmtbegin;
426-
fmtpar[fmtpos].fmtend=format;
427-
fmtpar[fmtpos].value=strvalue;
428-
fmtpar[fmtpos].ljust=ljust;
429-
fmtpar[fmtpos].len=len;
430-
fmtpar[fmtpos].zpad=zpad;
431-
fmtpar[fmtpos].maxwidth=maxwidth;
432-
fmtpar[fmtpos].func=FMTSTR;
433-
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
434-
fmtpos++;
435-
}
384+
fmtpar[fmtpos].fmtbegin=fmtbegin;
385+
fmtpar[fmtpos].fmtend=format;
386+
fmtpar[fmtpos].ljust=ljust;
387+
fmtpar[fmtpos].len=len;
388+
fmtpar[fmtpos].zpad=zpad;
389+
fmtpar[fmtpos].maxwidth=maxwidth;
390+
fmtpar[fmtpos].func=FMTSTR;
391+
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
392+
fmtpos++;
436393
break;
437394
case'c':
438-
ch=va_arg(args,int);
439395
fmtpar[fmtpos].fmtbegin=fmtbegin;
440396
fmtpar[fmtpos].fmtend=format;
441-
fmtpar[fmtpos].charvalue=ch;
442397
fmtpar[fmtpos].func=FMTCHAR;
443398
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
444399
fmtpos++;
@@ -448,15 +403,13 @@ dopr(char *buffer, const char *format, va_list args, char *end)
448403
case'f':
449404
case'g':
450405
case'G':
451-
fvalue=va_arg(args,double);
452406
fmtpar[fmtpos].fmtbegin=fmtbegin;
453407
fmtpar[fmtpos].fmtend=format;
454-
fmtpar[fmtpos].fvalue=fvalue;
455408
fmtpar[fmtpos].type=ch;
456409
fmtpar[fmtpos].ljust=ljust;
457410
fmtpar[fmtpos].len=len;
458411
fmtpar[fmtpos].maxwidth=maxwidth;
459-
fmtpar[fmtpos].precision=position;
412+
fmtpar[fmtpos].precision=precision;
460413
fmtpar[fmtpos].pointflag=pointflag;
461414
fmtpar[fmtpos].func=FMTFLOAT;
462415
fmtpar[fmtpos].realpos=realpos?realpos:fmtpos;
@@ -473,22 +426,74 @@ dopr(char *buffer, const char *format, va_list args, char *end)
473426
break;
474427
}
475428
}
429+
476430
performpr:
477-
/*shuffle pointers */
431+
/*reorder pointers */
478432
for(i=1;i<fmtpos;i++)
479433
fmtparptr[i]=&fmtpar[fmtpar[i].realpos];
434+
435+
/* assign values */
436+
for(i=1;i<fmtpos;i++){
437+
switch(fmtparptr[i]->func){
438+
caseFMTSTR:
439+
fmtparptr[i]->value=va_arg(args,char*);
440+
break;
441+
caseFMTNUM:
442+
if (fmtparptr[i]->longflag)
443+
{
444+
if (fmtparptr[i]->longlongflag)
445+
fmtparptr[i]->numvalue=va_arg(args,int64);
446+
else
447+
fmtparptr[i]->numvalue=va_arg(args,long);
448+
}
449+
else
450+
fmtparptr[i]->numvalue=va_arg(args,int);
451+
break;
452+
caseFMTNUM_U:
453+
if (fmtparptr[i]->longflag)
454+
{
455+
if (fmtparptr[i]->longlongflag)
456+
fmtparptr[i]->numvalue=va_arg(args,uint64);
457+
else
458+
fmtparptr[i]->numvalue=va_arg(args,unsignedlong);
459+
}
460+
else
461+
fmtparptr[i]->numvalue=va_arg(args,unsignedint);
462+
break;
463+
caseFMTFLOAT:
464+
fmtparptr[i]->fvalue=va_arg(args,double);
465+
break;
466+
caseFMTCHAR:
467+
fmtparptr[i]->charvalue=va_arg(args,int);
468+
break;
469+
caseFMTLEN:
470+
if (i+1<fmtpos&&fmtpar[i+1].func!=FMTWIDTH)
471+
fmtpar[i+1].len=va_arg(args,int);
472+
/* For "%*.*f", use the second arg */
473+
if (i+2<fmtpos&&fmtpar[i+1].func==FMTWIDTH)
474+
fmtpar[i+2].len=va_arg(args,int);
475+
break;
476+
caseFMTWIDTH:
477+
if (i+1<fmtpos)
478+
fmtpar[i+1].maxwidth=fmtpar[i+1].precision=
479+
va_arg(args,int);
480+
break;
481+
}
482+
}
483+
484+
/* do the output */
480485
output=buffer;
481486
format=format_save;
482487
while ((ch=*format++))
483488
{
484489
for(i=1;i<fmtpos;i++)
485490
{
486-
if(ch=='%'&&*format=='%')
491+
if(ch=='%'&&*format=='%')
487492
{
488493
format++;
489494
continue;
490495
}
491-
if(fmtpar[i].fmtbegin==format-1)
496+
if(fmtpar[i].fmtbegin==format-1)
492497
{
493498
switch(fmtparptr[i]->func){
494499
caseFMTSTR:
@@ -497,6 +502,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
497502
fmtparptr[i]->maxwidth,end,&output);
498503
break;
499504
caseFMTNUM:
505+
caseFMTNUM_U:
500506
fmtnum(fmtparptr[i]->numvalue,fmtparptr[i]->base,
501507
fmtparptr[i]->dosign,fmtparptr[i]->ljust,
502508
fmtparptr[i]->len,fmtparptr[i]->zpad,end,&output);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp