Skip to content

Commit d838bc8

Browse files
committed
vcardtime.c, vcardvalue.c: don't use sscanf("%m$") formats
1 parent 7fd1353 commit d838bc8

File tree

2 files changed

+150
-97
lines changed

2 files changed

+150
-97
lines changed

Diff for: src/libicalvcard/vcardtime.c

+134-88
Original file line numberDiff line numberDiff line change
@@ -139,60 +139,111 @@ int vcardtime_is_valid_time(const struct vcardtimetype t)
139139

140140
static int sprintf_date(const vcardtimetype t, char *buf, size_t size)
141141
{
142-
/* 3 zero-padded numeric arguments by position + NUL */
143-
char fmt[19] = "";
142+
/*
143+
date = year [month day]
144+
/ year "-" month
145+
/ "--" month [day]
146+
/ "--" "-" day
147+
*/
148+
const char *fmt;
144149

145150
if (t.year != -1) {
146-
strcat(fmt, "%04d");
151+
if (t.month == -1) {
152+
fmt = "%04d";
153+
}
154+
else if (t.day == -1) {
155+
fmt = "%04d-%02d";
156+
}
157+
else {
158+
fmt = "%04d%02d%02d";
159+
}
147160

148-
if (t.month != -1) {
149-
strcat(fmt, (t.day != -1) ? "%02d%02d" : "-%02d");
161+
return snprintf(buf, size, fmt, t.year, t.month, t.day);
162+
}
163+
else if (t.month != -1) {
164+
if (t.day == -1) {
165+
fmt = "--%02d";
150166
}
167+
else {
168+
fmt = "--%02d%02d";
169+
}
170+
171+
return snprintf(buf, size, fmt, t.month, t.day);
151172
}
152173
else {
153-
strcat(fmt, "--");
154-
155-
strcat(fmt, (t.month != -1) ? "%2$02d" : "-");
156-
157-
if (t.day != -1) {
158-
strcat(fmt, "%3$02d");
159-
}
174+
return snprintf(buf, size, "---%02d", t.day);
160175
}
161-
162-
return snprintf(buf, size, fmt, t.year, t.month, t.day);
163176
}
164177

165178
static int sprintf_time(const vcardtimetype t, int need_designator,
166179
char *buf, size_t size)
167180
{
168-
/* "T" + sign + 5 zero-padded numeric arguments by position + NUL */
169-
char fmt[33] = "";
181+
/*
182+
time = ["T"] hour [minute [second]] [zone]
183+
/ ["T"] "-" minute [second]
184+
/ ["T"] "-" "-" second
185+
*/
186+
const char *fmt;
170187

171188
if (need_designator) {
172-
strcat(fmt, "T");
189+
strncat(buf, "T", size);
190+
buf++;
191+
size--;
173192
}
174193

175194
if (t.hour != -1) {
176-
strcat(fmt, "%02d");
195+
/* hour [minute [second]] [zone] */
196+
int n;
177197

178-
if (t.minute != -1) {
179-
strcat(fmt, (t.second != -1) ? "%02d%02d" : "%02d");
198+
if (t.minute == -1) {
199+
/* hour */
200+
fmt = "%02d";
201+
}
202+
else if (t.second == -1) {
203+
/* hour minute */
204+
fmt = "%02d%02d";
205+
}
206+
else {
207+
/* hour minute second */
208+
fmt = "%02d%02d%02d";
180209
}
181210

211+
n = snprintf(buf, size, fmt, t.hour, t.minute, t.second);
212+
182213
if (t.utcoffset != -1) {
183-
strcat(fmt, (t.utcoffset == 0) ? "Z" : "%4$+03d%5$02d");
184-
}
185-
}
186-
else {
187-
strcat(fmt, (t.minute != -1) ? "-%2$02d" : "--");
214+
/* zone = "Z" / ( sign hour minute ) */
215+
buf += n;
216+
size -= n;
188217

189-
if (t.second != -1) {
190-
strcat(fmt, "%3$02d");
218+
if (t.utcoffset == 0) {
219+
strncpy(buf, "Z", size);
220+
n++;
221+
}
222+
else {
223+
n += snprintf(buf, size, "%+03d%02d",
224+
t.utcoffset / 60, abs(t.utcoffset % 60));
225+
}
191226
}
227+
228+
return n;
192229
}
230+
else if (t.minute != -1) {
231+
/* "-" minute [second] */
232+
if (t.second == -1) {
233+
/* "-" minute */
234+
fmt = "-%02d";
235+
}
236+
else {
237+
/* "-" minute second */
238+
fmt = "-%02d%02d";
239+
}
193240

194-
return snprintf(buf, size, fmt, t.hour, t.minute, t.second,
195-
t.utcoffset / 60, abs(t.utcoffset % 60));
241+
return snprintf(buf, size, fmt, t.minute, t.second);
242+
}
243+
else {
244+
/* "-" "-" second */
245+
return snprintf(buf, size, "--%02d", t.second);
246+
}
196247
}
197248

198249
char *vcardtime_as_vcard_string_r(const vcardtimetype t,
@@ -232,10 +283,15 @@ const char *vcardtime_as_vcard_string(const vcardtimetype t,
232283

233284
static const char *sscanf_date(const char *str, vcardtimetype *t)
234285
{
235-
char fmt[TIME_BUF_SIZE] = ""; /* 4 numeric arguments by position + NUL */
286+
/*
287+
date = year [month day]
288+
/ year "-" month
289+
/ "--" month [day]
290+
/ "--" "-" day
291+
*/
236292
const char *month;
237293
size_t ndig;
238-
int nchar;
294+
int nchar = 0;
239295
char *newstr;
240296

241297
if (!str || !*str) {
@@ -246,181 +302,171 @@ static const char *sscanf_date(const char *str, vcardtimetype *t)
246302
month = str + 2;
247303

248304
if (*month == '-') {
249-
/* "--" "-" day */
250305
ndig = num_digits(month+1);
251306

252307
if (ndig == 2) {
253-
strcpy(fmt, "---%3$2u");
308+
sscanf(str, "---%2u%n", &t->day, &nchar);
254309
}
255310
}
256311
else {
257-
/* "--" month [day] */
258312
ndig = num_digits(month);
259313

260314
if (ndig == 4) {
261-
/* month day */
262-
strcpy(fmt, "--%2$2u%3$2u");
315+
sscanf(str, "--%2u%2u%n", &t->month, &t->day, &nchar);
263316
}
264317
else if (ndig == 2) {
265-
/* month */
266-
strcpy(fmt, "--%2$2u");
318+
sscanf(str, "--%2u%n", &t->month, &nchar);
267319
}
268320
}
269321
}
270322
else {
271-
/* year [ ("-" month) / (month day)] */
272323
ndig = num_digits(str);
273324

274325
if (ndig == 8) {
275-
/* year month day */
276-
strcpy(fmt, "%1$4u%2$2u%3$2u");
326+
sscanf(str, "%4u%2u%2u%n", &t->year, &t->month, &t->day, &nchar);
277327
}
278328
else if (ndig == 4) {
279329
month = str + 4;
280330

281331
if (!*month) {
282-
/* year */
283-
strcpy(fmt, "%1$4u");
332+
sscanf(str, "%4u%n", &t->year, &nchar);
284333
}
285334
else if (*month == '-') {
286-
/* year "-" month [ "-" day ] */
287335
ndig = num_digits(++month);
288336

289337
if (ndig == 2) {
290-
strcpy(fmt, "%1$4u-%2$2u");
291-
292338
if (month[2] == '-') {
293-
strcat(fmt, "-%3$2u");
339+
sscanf(str, "%4u-%2u-%2u%n",
340+
&t->year, &t->month, &t->day, &nchar);
341+
}
342+
else {
343+
sscanf(str, "%4u-%2u%n",
344+
&t->year, &t->month, &nchar);
294345
}
295346
}
296347
}
297348
}
298349
}
299350

300-
if (!*fmt) {
351+
if (!nchar) {
301352
/* invalid time */
302353
return NULL;
303354
}
304355

305-
strcat(fmt, "%4$n");
306-
sscanf(str, fmt, &t->year, &t->month, &t->day, &nchar);
307-
308356
newstr = (char *)str + nchar;
309357
return newstr;
310358
}
311359

312360
static const char *sscanf_zone(const char *str, vcardtimetype *t)
313361
{
314-
char fmt[16] = ""; /* 3 numeric arguments by position + NUL */
315-
int offset_h = 0, offset_m = 0, nchar;
362+
/*
363+
zone = "Z"
364+
/ ( "+" / "-" ) hour [minute]
365+
*/
366+
unsigned offset_h = 0, offset_m = 0;
367+
char sign[2] = "";
316368
size_t ndig;
317369
char *newstr;
370+
int nchar = 0;
318371

319372
if (!str || !*str) {
320373
/* empty string */
321374
return NULL;
322375
}
323376
else if (*str == 'Z') {
324-
/* zone = utc-designator */
325-
strcpy(fmt, "Z");
377+
nchar = 1;
326378
}
327379
else if (strchr("+-", *str)) {
328-
/* zone = utc-offset = sign hour [minute] */
329380
ndig = num_digits(str+1);
330381

331382
if (ndig == 4) {
332-
/* sign hour minute */
333-
strcpy(fmt, "%1$3d%2$2u");
383+
sscanf(str, "%1[+-]%2u%2u%n", sign, &offset_h, &offset_m, &nchar);
334384
}
335385
else if (ndig == 2) {
336-
/* sign hour */
337-
strcpy(fmt, "%1$3d");
386+
sscanf(str, "%1[+-]%2u%n", sign, &offset_h, &nchar);
338387
}
339388
}
340389

341-
if (!*fmt) {
390+
if (!nchar) {
342391
/* invalid zone */
343392
return NULL;
344393
}
345394

346-
strcat(fmt, "%3$n");
347-
sscanf(str, fmt, &offset_h, &offset_m, &nchar);
348-
349-
t->utcoffset = 60 * offset_h + ((offset_h < 0) ? -offset_m : offset_m);
395+
t->utcoffset = 60 * offset_h + offset_m;
396+
if (*sign == '-') t->utcoffset = -t->utcoffset;
350397

351398
newstr = (char *)str + nchar;
352399
return newstr;
353400
}
354401

355402
static const char *sscanf_time(const char *str, vcardtimetype *t)
356403
{
357-
char fmt[27] = ""; /* "%1$2u:%2$2u:%3$2u.%4$u%5$n" + NUL */
404+
/*
405+
time = hour [ ":" minute ":" second [ "." secfrac ] ]
406+
/ hour [ minute [second]] [zone]
407+
/ "-" minute [second]
408+
/ "-" "-" second
409+
*/
358410
unsigned secfrac;
359411
size_t ndig;
360-
int nchar;
412+
int nchar = 0;
361413

362414
if (!str || !*str) {
363415
/* empty string */
364416
return NULL;
365417
}
366418
else if (*str == '-') {
367419
if (str[1] == '-') {
368-
/* "-" "-" second */
369420
ndig = num_digits(str+2);
370421

371422
if (ndig == 2) {
372-
strcpy(fmt, "--%3$2u");
423+
sscanf(str, "--%2u%n", &t->second, &nchar);
373424
}
374425
}
375426
else {
376-
/* "-" minute [second] */
377427
ndig = num_digits(str+1);
378428

379429
if (ndig == 4) {
380-
/* minute second */
381-
strcpy(fmt, "-%2$2u%3$2u");
430+
sscanf(str, "-%2u%2u%n", &t->minute, &t->second, &nchar);
382431
}
383432
else if (ndig == 2) {
384-
/* minute */
385-
strcpy(fmt, "-%2$2u");
433+
sscanf(str, "-%2u%n", &t->minute, &nchar);
386434
t->second = 0;
387435
}
388436
}
389437
}
390438
else {
391-
/* hour [minute [second]] [zone] */
392439
ndig = num_digits(str);
393440

394441
if (ndig == 6) {
395-
/* hour minute second */
396-
strcpy(fmt, "%1$2u%2$2u%3$2u");
442+
sscanf(str, "%2u%2u%2u%n", &t->hour, &t->minute, &t->second, &nchar);
397443
}
398444
else if (ndig == 4) {
399-
/* hour minute */
400-
strcpy(fmt, "%1$2u%2$2u");
445+
sscanf(str, "%2u%2u%n", &t->hour, &t->minute, &nchar);
401446
t->second = 0;
402447
}
403448
else if (ndig == 2) {
404-
/* hour [ ":" minute ":" second [ "." secfrac ] ] */
405-
strcpy(fmt, "%1$2u");
406-
407449
if (str[2] == ':') {
408-
strcat(fmt, ":%2$2u:%3$2u");
409-
410450
if (str[8] == '.') {
411-
strcat(fmt, ".%4$u");
451+
sscanf(str, "%2u:%2u:%2u.%u%n",
452+
&t->hour, &t->minute, &t->second, &secfrac, &nchar);
412453
}
454+
else {
455+
sscanf(str, "%2u:%2u:%2u%n",
456+
&t->hour, &t->minute, &t->second, &nchar);
457+
}
458+
}
459+
else {
460+
sscanf(str, "%2u%n", &t->hour, &nchar);
413461
}
414462
}
415463
}
416464

417-
if (!*fmt) {
465+
if (!nchar) {
418466
/* invalid time */
419467
return NULL;
420468
}
421469

422-
strcat(fmt, "%5$n");
423-
sscanf(str, fmt, &t->hour, &t->minute, &t->second, &secfrac, &nchar);
424470
str += nchar;
425471

426472
if (t->hour != -1 && *str) {

0 commit comments

Comments
 (0)