summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@netfilter.org>2023-12-12 09:24:43 +0100
committerJozsef Kadlecsik <kadlec@netfilter.org>2023-12-12 09:24:43 +0100
commitca62c0e1640e5d112679044434227024690b53bc (patch)
tree7203fc52711aa458c1107646bc27be1269cd5a68
parentb15dd2752a2d666358a42285528805bf2835f6c6 (diff)
Fix hex literals in json output
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>
-rw-r--r--include/libipset/session.h2
-rw-r--r--lib/print.c19
-rw-r--r--lib/session.c31
3 files changed, 29 insertions, 23 deletions
diff --git a/include/libipset/session.h b/include/libipset/session.h
index f0da10f..365e17e 100644
--- a/include/libipset/session.h
+++ b/include/libipset/session.h
@@ -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,
diff --git a/lib/print.c b/lib/print.c
index 50f0ad6..6ea79cb 100644
--- a/lib/print.c
+++ b/lib/print.c
@@ -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;
diff --git a/lib/session.c b/lib/session.c
index a10238d..944e002 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -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 */