8000 libmount: don't use sscanf() for swaps parsing · util-linux/util-linux@6c9ab25 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6c9ab25

Browse files
committed
libmount: don't use sscanf() for swaps parsing
Addresses: #780 Signed-off-by: Karel Zak <kzak@redhat.com>
1 parent 86673b3 commit 6c9ab25

File tree

2 files changed

+74
-47
lines changed

2 files changed

+74
-47
lines changed

include/pathnames.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
/* used by kernel in /proc (e.g. /proc/swaps) for deleted files */
1818
#define PATH_DELETED_SUFFIX " (deleted)"
19-
#define PATH_DELETED_SUFFIX_SZ (sizeof(PATH_DELETED_SUFFIX) - 1)
2019

2120
/* DEFPATHs from <paths.h> don't include /usr/local */
2221
#undef _PATH_DEFPATH

libmount/src/tab_parse.c

Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,35 @@ static void parser_cleanup(struct libmnt_parser *pa)
4343
memset(pa, 0, sizeof(*pa));
4444
}
4545

46-
static const char *next_number(const char *s, int *num, int *rc)
46+
static const char *next_s32(const char *s, int *num, int *rc)
4747
{
4848
char *end = NULL;
4949

5050
if (!s || !*s)
5151
return s;
5252

53-
assert(num);
54-
assert(rc);
55-
5653
*rc = -EINVAL;
5754
*num = strtol(s, &end, 10);
5855
if (end == NULL || s == end)
5956
return s;
60-
61-
/* valid end of number is a space or a terminator */
6257
if (*end == ' ' || *end == '\t' || *end == '\0')
6358
*rc = 0;
59+
return end;
60+
}
61+
62+
static const char *next_u64(const char *s, uint64_t *num, int *rc)
63+
{
64+
char *end = NULL;
6465

66+
if (!s || !*s)
67+
return s;
68+
69+
*rc = -EINVAL;
70+
*num = (uint64_t) strtoumax(s, &end, 10);
71+
if (end == NULL || s == end)
72+
return s;
73+
if (*end == ' ' || *end == '\t' || *end == '\0')
74+
*rc = 0;
6575
return end;
6676
}
6777

@@ -130,7 +140,7 @@ static int mnt_parse_table_line(struct libmnt_fs *fs, const char *s)
130140
goto done;
131141

132142
/* (5) freq (optional) */
133-
s = next_number(s, &fs->freq, &rc);
143+
s = next_s32(s, &fs->freq, &rc);
134144
if (s && *s && rc) {
135145
DBG(TAB, ul_debug("tab parse error: [freq]"));
136146
goto fail;
@@ -141,7 +151,7 @@ static int mnt_parse_table_line(struct libmnt_fs *fs, const char *s)
141151
goto done;
142152

143153
/* (6) freq (optional) */
144-
s = next_number(s, &fs->passno, &rc);
154+
s = next_s32(s, &fs->passno, &rc);
145155
if (s && *s && rc) {
146156
DBG(TAB, ul_debug("tab parse error: [passno]"));
147157
goto fail;
@@ -169,7 +179,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, const char *s)
169179
fs->flags |= MNT_FS_KERNEL;
170180

171181
/* (1) id */
172-
s = next_number(s, &fs->id, &rc);
182+
s = next_s32(s, &fs->id, &rc);
173183
if (!s || !*s || rc) {
174184
DBG(TAB, ul_debug("tab parse error: [id]"));
175185
goto fail;
@@ -178,7 +188,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, const char *s)
178188
s = skip_separator(s);
179189

180190
/* (2) parent */
181-
s = next_number(s, &fs->parent, &rc);
191+
s = next_s32(s, &fs->parent, &rc);
182192
if (!s || !*s || rc) {
183193
DBG(TAB, ul_debug("tab parse error: [parent]"));
184194
goto fail;
@@ -355,48 +365,66 @@ static int mnt_parse_utab_line(struct libmnt_fs *fs, const char *s)
355365
*/
356366
static int mnt_parse_swaps_line(struct libmnt_fs *fs, const char *s)
357367
{
358-
uintmax_t fsz, usz;
368+
uint64_t num;
359369
int rc;
360-
char *src = NULL;
361-
362-
rc = sscanf(s, UL_SCNsA" " /* (1) source */
363-
UL_SCNsA" " /* (2) type */
364-
"%ju" /* (3) size */
365-
"%ju" /* (4) used */
366-
"%d", /* priority */
367-
368-
&src,
369-
&fs->swaptype,
370-
&fsz,
371-
&usz,
372-
&fs->priority);
373-
374-
if (rc == 5) {
375-
size_t sz;
376-
377-
fs->size = fsz;
378-
fs->usedsize = usz;
379-
380-
/* remove "\040(deleted)" suffix */
381-
sz = strlen(src);
382-
if (sz > PATH_DELETED_SUFFIX_SZ) {
383-
char *p = src + (sz - PATH_DELETED_SUFFIX_SZ);
384-
if (strcmp(p, PATH_DELETED_SUFFIX) == 0)
385-
*p = '\0';
386-
}
370+
char *p;
387371

388-
unmangle_string(src);
372+
/* (1) source */
373+
p = unmangle(s, &s);
374+
if (p) {
375+
char *x = (char *) endswith(p, PATH_DELETED_SUFFIX);
376+
if (x && *x)
377+
*x = '\0';
378+
}
379+
if (!p || (rc = __mnt_fs_set_source_ptr(fs, p))) {
380+
DBG(TAB, ul_debug("tab parse error: [source]"));
381+
goto fail;
382+
}
389383

390-
rc = mnt_fs_set_source(fs, src);
391-
if (!rc)
392-
mnt_fs_set_fstype(fs, "swap");
393-
} else {
394-
DBG(TAB, ul_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s));
395-
rc = -EINVAL;
384+
s = skip_separator(s);
385+
386+
/* (2) type */
387+
fs->swaptype = unmangle(s, &s);
388+
if (!fs->swaptype) {
389+
DBG(TAB, ul_debug("tab parse error: [swaptype]"));
390+
goto fail;
391+
}
392+
393+
s = skip_separator(s);
394+
395+
/* (3) size */
396+
s = next_u64(s, &num, &rc);
397+
if (!s || !*s || rc) {
398+
DBG(TAB, ul_debug("tab parse error: [size]"));
399+
goto fail;
400+
}
401+
fs->size = num;
402+
403+
s = skip_separator(s);
404+
405+
/* (4) size */
406+
s = next_u64(s, &num, &rc);
407+
if (!s || !*s || rc) {
408+
DBG(TAB, ul_debug("tab parse error: [used size]"));
409+
goto fail;
396410
}
411+
fs->usedsize = num;
397412

398-
free(src);
413+
s = skip_separator(s);
399414

415+
/* (5) priority */
416+
s = next_s32(s, &fs->priority, &rc);
417+
if (rc) {
418+
DBG(TAB, ul_debug("tab parse error: [priority]"));
419+
goto fail;
420+
}
421+
422+
mnt_fs_set_fstype(fs, "swap");
423+
return 0;
424+
fail:
425+
if (rc == 0)
426+
rc = -EINVAL;
427+
DBG(TAB, ul_debug("tab parse error on: '%s' [rc=%d]", s, rc));
400428
return rc;
401429
}
402430

0 commit comments

Comments
 (0)
0