]> git.ipfire.org Git - thirdparty/ipset.git/commitdiff
Fix hex literals in json output
authorJozsef Kadlecsik <kadlec@netfilter.org>
Tue, 12 Dec 2023 08:24:43 +0000 (09:24 +0100)
committerJozsef Kadlecsik <kadlec@netfilter.org>
Tue, 12 Dec 2023 08:24:43 +0000 (09:24 +0100)
Json does not allow 0x prefixes in hex numbers, so output hex numbers
as quoted strings instead.

Fixes bugzilla #1726, reported by Mark.

Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
include/libipset/session.h
lib/print.c
lib/session.c

index f0da10f51a2ca7660fc00a0eb7846d0efa368b2f..365e17e63b2238c32f6957f445ed2f366234b566 100644 (file)
@@ -84,6 +84,8 @@ enum ipset_envopt {
        IPSET_ENV_LIST_SETNAME  = (1 << IPSET_ENV_BIT_LIST_SETNAME),
        IPSET_ENV_BIT_LIST_HEADER = 5,
        IPSET_ENV_LIST_HEADER   = (1 << IPSET_ENV_BIT_LIST_HEADER),
+       IPSET_ENV_BIT_QUOTED    = 6,
+       IPSET_ENV_QUOTED        = (1 << IPSET_ENV_BIT_QUOTED),
 };
 
 extern bool ipset_envopt_test(struct ipset_session *session,
index 50f0ad6e4aaa7a9b97e7873de5f9a322e2eee078..6ea79cb421636501819a65c3a1342c8a089e8c03 100644 (file)
@@ -411,10 +411,11 @@ ipset_print_number(char *buf, unsigned int len,
 int
 ipset_print_hexnumber(char *buf, unsigned int len,
                      const struct ipset_data *data, enum ipset_opt opt,
-                     uint8_t env UNUSED)
+                     uint8_t env)
 {
        size_t maxsize;
        const void *number;
+       const char *quoted = env & IPSET_ENV_QUOTED ? "\"" : "";
 
        assert(buf);
        assert(len > 0);
@@ -424,17 +425,17 @@ ipset_print_hexnumber(char *buf, unsigned int len,
        maxsize = ipset_data_sizeof(opt, AF_INET);
        D("opt: %u, maxsize %zu", opt, maxsize);
        if (maxsize == sizeof(uint8_t))
-               return snprintf(buf, len, "0x%02"PRIx8,
-                               *(const uint8_t *) number);
+               return snprintf(buf, len, "%s0x%02"PRIx8"%s",
+                               quoted, *(const uint8_t *) number, quoted);
        else if (maxsize == sizeof(uint16_t))
-               return snprintf(buf, len, "0x%04"PRIx16,
-                               *(const uint16_t *) number);
+               return snprintf(buf, len, "%s0x%04"PRIx16"%s",
+                               quoted, *(const uint16_t *) number, quoted);
        else if (maxsize == sizeof(uint32_t))
-               return snprintf(buf, len, "0x%08"PRIx32,
-                               *(const uint32_t *) number);
+               return snprintf(buf, len, "%s0x%08"PRIx32"%s",
+                               quoted, *(const uint32_t *) number, quoted);
        else if (maxsize == sizeof(uint64_t))
-               return snprintf(buf, len, "0x%016"PRIx64,
-                               *(const uint64_t *) number);
+               return snprintf(buf, len, "%s0x%016"PRIx64"%s",
+                               quoted, *(const uint64_t *) number, quoted);
        else
                assert(0);
        return 0;
index a10238d87ec1abf8353e79d92b67d0e3509a555e..944e002ff5c4e57e8dad3c3d0bc3ff38765f0e2a 100644 (file)
@@ -2277,23 +2277,26 @@ ipset_cmd(struct ipset_session *session, enum ipset_cmd cmd, uint32_t lineno)
        session->cmd = cmd;
        session->lineno = lineno;
 
-       /* Set default output mode */
-       if (cmd == IPSET_CMD_LIST) {
+       if (cmd == IPSET_CMD_LIST || cmd == IPSET_CMD_SAVE) {
+               /* Set default output mode */
                if (session->mode == IPSET_LIST_NONE)
                        session->mode = IPSET_LIST_PLAIN;
-       } else if (cmd == IPSET_CMD_SAVE) {
-               if (session->mode == IPSET_LIST_NONE)
-                       session->mode = IPSET_LIST_SAVE;
+               /* Reset just in case there are multiple modes in a session */
+               ipset_envopt_unset(session, IPSET_ENV_QUOTED);
+               switch (session->mode) {
+               case IPSET_LIST_XML:
+                       /* Start the root element in XML mode */
+                       safe_snprintf(session, "<ipsets>\n");
+                       break;
+               case IPSET_LIST_JSON:
+                       /* Start the root element in json mode */
+                       ipset_envopt_set(session, IPSET_ENV_QUOTED);
+                       safe_snprintf(session, "[\n");
+                       break;
+               default:
+                       break;
+               }
        }
-       /* Start the root element in XML mode */
-       if ((cmd == IPSET_CMD_LIST || cmd == IPSET_CMD_SAVE) &&
-           session->mode == IPSET_LIST_XML)
-               safe_snprintf(session, "<ipsets>\n");
-
-       /* Start the root element in json mode */
-       if ((cmd == IPSET_CMD_LIST || cmd == IPSET_CMD_SAVE) &&
-           session->mode == IPSET_LIST_JSON)
-               safe_snprintf(session, "[\n");
 
        D("next: build_msg");
        /* Build new message or append buffered commands */