Skip to content

Commit 37f85ec

Browse files
committed
(core_backup.c) Remove sscanf and also fix memory leak
1 parent d6d483c commit 37f85ec

1 file changed

Lines changed: 92 additions & 7 deletions

File tree

core_backup.c

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ static bool core_backup_add_entry(core_backup_list_t *backup_list,
391391
{
392392
char *backup_filename = NULL;
393393
core_backup_list_entry_t *entry = NULL;
394+
const char *p = NULL;
395+
char *endptr = NULL;
394396
unsigned long crc = 0;
395397
unsigned backup_mode = 0;
396398

@@ -401,9 +403,11 @@ static bool core_backup_add_entry(core_backup_list_t *backup_list,
401403
return false;
402404

403405
backup_filename = strdup(path_basename(backup_path));
404-
405406
if (string_is_empty(backup_filename))
407+
{
408+
free(backup_filename);
406409
return false;
410+
}
407411

408412
/* Ensure base backup filename matches core */
409413
if (!string_starts_with(backup_filename, core_filename))
@@ -420,11 +424,93 @@ static bool core_backup_add_entry(core_backup_list_t *backup_list,
420424
* - timestamp: YYYYMMDDTHHMMSS */
421425
entry = &backup_list->entries[backup_list->size];
422426

423-
if (sscanf(backup_filename + strlen(core_filename),
424-
".%04u%02u%02uT%02u%02u%02u.%08lx.%u",
425-
&entry->date.year, &entry->date.month, &entry->date.day,
426-
&entry->date.hour, &entry->date.minute, &entry->date.second,
427-
&crc, &backup_mode) != 8)
427+
p = backup_filename + strlen(core_filename);
428+
429+
/* Expect '.' separator before timestamp */
430+
if (*p != '.')
431+
{
432+
free(backup_filename);
433+
return false;
434+
}
435+
p++;
436+
437+
/* Timestamp must be exactly 15 characters: YYYYMMDDTHHMMSS */
438+
if (strlen(p) < 15 || p[8] != 'T')
439+
{
440+
free(backup_filename);
441+
return false;
442+
}
443+
444+
/* Parse date/time components */
445+
{
446+
char buf[5];
447+
448+
/* Year (4 digits) */
449+
memcpy(buf, p, 4);
450+
buf[4] = '\0';
451+
entry->date.year = (unsigned)strtoul(buf, &endptr, 10);
452+
if (*endptr != '\0') { free(backup_filename); return false; }
453+
p += 4;
454+
455+
/* Month (2 digits) */
456+
memcpy(buf, p, 2);
457+
buf[2] = '\0';
458+
entry->date.month = (unsigned)strtoul(buf, &endptr, 10);
459+
if (*endptr != '\0') { free(backup_filename); return false; }
460+
p += 2;
461+
462+
/* Day (2 digits) */
463+
memcpy(buf, p, 2);
464+
buf[2] = '\0';
465+
entry->date.day = (unsigned)strtoul(buf, &endptr, 10);
466+
if (*endptr != '\0') { free(backup_filename); return false; }
467+
p += 2;
468+
469+
/* Skip 'T' separator */
470+
p++;
471+
472+
/* Hour (2 digits) */
473+
memcpy(buf, p, 2);
474+
buf[2] = '\0';
475+
entry->date.hour = (unsigned)strtoul(buf, &endptr, 10);
476+
if (*endptr != '\0') { free(backup_filename); return false; }
477+
p += 2;
478+
479+
/* Minute (2 digits) */
480+
memcpy(buf, p, 2);
481+
buf[2] = '\0';
482+
entry->date.minute = (unsigned)strtoul(buf, &endptr, 10);
483+
if (*endptr != '\0') { free(backup_filename); return false; }
484+
p += 2;
485+
486+
/* Second (2 digits) */
487+
memcpy(buf, p, 2);
488+
buf[2] = '\0';
489+
entry->date.second = (unsigned)strtoul(buf, &endptr, 10);
490+
if (*endptr != '\0') { free(backup_filename); return false; }
491+
p += 2;
492+
}
493+
494+
/* Expect '.' separator before CRC */
495+
if (*p != '.')
496+
{
497+
free(backup_filename);
498+
return false;
499+
}
500+
p++;
501+
502+
/* Parse 8-character hex CRC */
503+
crc = strtoul(p, &endptr, 16);
504+
if (endptr != p + 8 || *endptr != '.')
505+
{
506+
free(backup_filename);
507+
return false;
508+
}
509+
p = endptr + 1;
510+
511+
/* Parse backup mode */
512+
backup_mode = (unsigned)strtoul(p, &endptr, 10);
513+
if (endptr == p || *endptr != '\0')
428514
{
429515
free(backup_filename);
430516
return false;
@@ -438,7 +524,6 @@ static bool core_backup_add_entry(core_backup_list_t *backup_list,
438524
backup_list->size++;
439525

440526
free(backup_filename);
441-
442527
return true;
443528
}
444529

0 commit comments

Comments
 (0)