Blob Blame History Raw
From ffed186cce8e5a20187f6f652be94e3135b74eed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 19 Oct 2022 08:41:13 +0200
Subject: [PATCH] shared/json: use different return code for empty input

It is useful to distinguish if json_parse_file() got no input or invalid input.
Use different return codes for the two cases.

(cherry picked from commit 87a16eb8b54002a49f12944fc09ce45d0cbadf45)

Related: #2149074
---
 src/shared/elf-util.c |  2 +-
 src/shared/json.c     |  6 ++++--
 src/test/test-json.c  | 18 ++++++++++++++++++
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c
index 6d9fcfbbf2..392ed9f31b 100644
--- a/src/shared/elf-util.c
+++ b/src/shared/elf-util.c
@@ -800,7 +800,7 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha
                         return -errno;
 
                 r = json_parse_file(json_in, NULL, 0, &package_metadata, NULL, NULL);
-                if (r < 0 && r != -EINVAL) /* EINVAL: json was empty, so we got nothing, but that's ok */
+                if (r < 0 && r != -ENODATA) /* ENODATA: json was empty, so we got nothing, but that's ok */
                         return r;
         }
 
diff --git a/src/shared/json.c b/src/shared/json.c
index f91738227b..70e46fabb1 100644
--- a/src/shared/json.c
+++ b/src/shared/json.c
@@ -3170,7 +3170,6 @@ int json_parse_continue(const char **p, JsonParseFlags flags, JsonVariant **ret,
 int json_parse_file_at(FILE *f, int dir_fd, const char *path, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
         _cleanup_(json_source_unrefp) JsonSource *source = NULL;
         _cleanup_free_ char *text = NULL;
-        const char *p;
         int r;
 
         if (f)
@@ -3182,13 +3181,16 @@ int json_parse_file_at(FILE *f, int dir_fd, const char *path, JsonParseFlags fla
         if (r < 0)
                 return r;
 
+        if (isempty(text))
+                return -ENODATA;
+
         if (path) {
                 source = json_source_new(path);
                 if (!source)
                         return -ENOMEM;
         }
 
-        p = text;
+        const char *p = text;
         return json_parse_internal(&p, source, flags, ret, ret_line, ret_column, false);
 }
 
diff --git a/src/test/test-json.c b/src/test/test-json.c
index b385edc269..2256492fb2 100644
--- a/src/test/test-json.c
+++ b/src/test/test-json.c
@@ -346,6 +346,24 @@ TEST(build) {
         assert_se(json_variant_equal(a, b));
 }
 
+TEST(json_parse_file_empty) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
+
+        assert_se(fopen_unlocked("/dev/null", "re", &f) >= 0);
+        assert_se(json_parse_file(f, "waldo", 0, &v, NULL, NULL) == -ENODATA);
+        assert_se(v == NULL);
+}
+
+TEST(json_parse_file_invalid) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
+
+        assert_se(f = fmemopen_unlocked((void*) "kookoo", 6, "r"));
+        assert_se(json_parse_file(f, "waldo", 0, &v, NULL, NULL) == -EINVAL);
+        assert_se(v == NULL);
+}
+
 TEST(source) {
         static const char data[] =
                 "\n"