Skip to content

Commit 4f5b813

Browse files
committed
Fix parsing unsigned integers: reject negative numbers
It is a documented Glib's misfeature to accept negative values in g_ascii_strtoull(). We need to reject negative numbers explicitly.
1 parent 441680b commit 4f5b813

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

modulemd/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ c_tests = {
355355
'module_index_merger' : [ 'tests/test-modulemd-merger.c' ],
356356
'modulestream' : [ 'tests/test-modulemd-modulestream.c' ],
357357
'packagerv3' : [ 'tests/test-modulemd-packager-v3.c' ],
358+
'parse_int64' : [ 'tests/test-modulemd-parse_int64.c' ],
358359
'profile' : [ 'tests/test-modulemd-profile.c' ],
359360
'rpm_map' : [ 'tests/test-modulemd-rpmmap.c' ],
360361
'service_level' : [ 'tests/test-modulemd-service-level.c' ],

modulemd/modulemd-yaml-util.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,17 @@ modulemd_yaml_parse_uint64 (yaml_parser_t *parser, GError **error)
453453

454454
g_debug ("Parsing scalar: %s", (const gchar *)event.data.scalar.value);
455455

456+
/* g_ascii_strtoull() accepts negative values by definition. */
457+
if (event.data.scalar.value[0] == '-')
458+
{
459+
g_set_error (error,
460+
MODULEMD_YAML_ERROR,
461+
MODULEMD_ERROR_VALIDATE,
462+
"%s: The integer value is negative",
463+
(const gchar *)event.data.scalar.value);
464+
return 0u;
465+
}
466+
456467
value =
457468
g_ascii_strtoull ((const gchar *)event.data.scalar.value, &endptr, 10);
458469

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* This file is part of libmodulemd
3+
* Copyright (C) 2021 Red Hat, Inc.
4+
*
5+
* Fedora-License-Identifier: MIT
6+
* SPDX-2.0-License-Identifier: MIT
7+
* SPDX-3.0-License-Identifier: MIT
8+
*
9+
* This program is free software.
10+
* For more information on the license, see COPYING.
11+
* For more information on free software, see <https://www.gnu.org/philosophy/free-sw.en.html>.
12+
*/
13+
14+
#include <glib.h>
15+
#include <locale.h>
16+
#include <string.h>
17+
18+
#include "private/modulemd-yaml.h"
19+
#include "private/test-utils.h"
20+
#include <yaml.h>
21+
22+
static void
23+
utest (const char *input, guint64 expected_value, gboolean expected_error)
24+
{
25+
guint64 parsed;
26+
g_autoptr (GError) error = NULL;
27+
MMD_INIT_YAML_EVENT (event);
28+
MMD_INIT_YAML_PARSER (parser);
29+
30+
yaml_parser_set_input_string (
31+
&parser, (const unsigned char *)input, strlen (input));
32+
parser_skip_document_start (&parser);
33+
34+
parsed = modulemd_yaml_parse_uint64 (&parser, &error);
35+
if (expected_error)
36+
g_assert_nonnull (error);
37+
else
38+
g_assert_null (error);
39+
g_assert_cmpuint (parsed, ==, expected_value);
40+
}
41+
42+
static void
43+
test_uint64_valid (void)
44+
{
45+
utest ("42", 42u, FALSE);
46+
}
47+
48+
static void
49+
test_uint64_invalid_no_digit (void)
50+
{
51+
utest ("foo", 0u, TRUE);
52+
}
53+
54+
static void
55+
test_uint64_invalid_incomplete (void)
56+
{
57+
utest ("42foo", 0u, TRUE);
58+
}
59+
60+
static void
61+
test_uint64_invalid_negative (void)
62+
{
63+
utest ("-42", 0u, TRUE);
64+
}
65+
66+
static void
67+
test_uint64_invalid_too_big (void)
68+
{
69+
utest ("18446744073709551616", 0u, TRUE);
70+
}
71+
72+
73+
int
74+
main (int argc, char *argv[])
75+
{
76+
setlocale (LC_ALL, "");
77+
g_test_init (&argc, &argv, NULL);
78+
79+
g_test_add_func ("/modulemd/v2/uint64/yaml/parse/valid", test_uint64_valid);
80+
g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_no_digit",
81+
test_uint64_invalid_no_digit);
82+
g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_incomplete",
83+
test_uint64_invalid_incomplete);
84+
g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_negative",
85+
test_uint64_invalid_negative);
86+
g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_too_big",
87+
test_uint64_invalid_too_big);
88+
89+
return g_test_run ();
90+
}

0 commit comments

Comments
 (0)