Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/zbxjson/json.c')
-rw-r--r--src/libs/zbxjson/json.c316
1 files changed, 166 insertions, 150 deletions
diff --git a/src/libs/zbxjson/json.c b/src/libs/zbxjson/json.c
index 6215e97db2e..c8422cde6a6 100644
--- a/src/libs/zbxjson/json.c
+++ b/src/libs/zbxjson/json.c
@@ -38,18 +38,17 @@ static char zbx_json_strerror_message[ZBX_JSON_MAX_STRERROR];
const char *zbx_json_strerror(void)
{
- zbx_json_strerror_message[ZBX_JSON_MAX_STRERROR - 1] = '\0'; /* force terminate string */
- return (&zbx_json_strerror_message[0]);
+ return zbx_json_strerror_message;
}
#ifdef HAVE___VA_ARGS__
# define zbx_set_json_strerror(fmt, ...) __zbx_zbx_set_json_strerror(ZBX_CONST_STRING(fmt), ##__VA_ARGS__)
#else
# define zbx_set_json_strerror __zbx_zbx_set_json_strerror
-#endif /* HAVE___VA_ARGS__ */
+#endif
static void __zbx_zbx_set_json_strerror(const char *fmt, ...)
{
- va_list args;
+ va_list args;
va_start(args, fmt);
@@ -553,166 +552,158 @@ const char *zbx_json_next(const struct zbx_json_parse *jp, const char *p)
return NULL;
}
-static size_t zbx_json_string_size(const char *p)
-{
- int state = 0; /* 0 - init; 1 - inside string */
- size_t sz = 0;
-
- if ('"' != *p)
- return (size_t)(-1);
-
- while ('\0' != *p) /* this should never happen */
- {
- if (*p == '"')
- {
- if (state == 1)
- return sz;
- state = 1;
- }
- else if (state == 1)
- {
- if (*p == '\\' && 'u' == *++p)
- p += 4;
- sz++;
- }
- p++;
- }
-
- return (size_t)(-1);
-}
-
-static const char *zbx_json_decodestring(const char *p, char *string, size_t len)
+static const char *zbx_json_decodenull(const char *p)
{
- int state = 0; /* 0 - init; 1 - inside string */
- char *o = string;
- u_char c;
-
- if ('"' != *p)
- return NULL;
-
- while ('\0' != *p) /* this should never happen */
- {
- if (*p == '"')
- {
- if (state == 1)
- {
- *o = '\0';
- return ++p;
- }
- state = 1;
- }
- else if (state == 1 && (size_t)(o - string) < len - 1/*'\0'*/)
- {
- if (*p == '\\')
- {
- switch (*++p)
- {
- case 'b':
- *o++ = '\b';
- break;
- case 'f':
- *o++ = '\f';
- break;
- case 'n':
- *o++ = '\n';
- break;
- case 'r':
- *o++ = '\r';
- break;
- case 't':
- *o++ = '\t';
- break;
- case 'u':
- p += 3; /* "u00" */
- c = zbx_hex2num(*p++) << 4;
- c += zbx_hex2num(*p);
- *o++ = (char)c;
- break;
- default:
- *o++ = *p;
- }
- }
- else
- *o++ = *p;
- }
-
- p++;
- }
+ if ('n' == p[0] && 'u' == p[1] && 'l' == p[2] && 'l' == p[3])
+ return p + 4;
return NULL;
}
-static size_t zbx_json_int_size(const char *p)
+/******************************************************************************
+ * *
+ * Function: zbx_json_decode_character *
+ * *
+ * Purpose: decodes escape character *
+ * *
+ * Parameters: p - [IN/OUT] a pointer to the next character in string *
+ * *
+ * Return value: 0 - invalid escape character *
+ * !0 - the escaped character *
+ * *
+ ******************************************************************************/
+static char zbx_json_decode_character(const char **p)
{
- size_t sz = 0;
+ char out;
- while (*p != '\0') /* this should never happen */
+ switch (*(++*p))
{
- if ((*p < '0' || *p > '9') && *p != '-')
- return sz;
- else
- sz++;
- p++;
+ case '"':
+ out = '"';
+ break;
+ case '\\':
+ out = '\\';
+ break;
+ case '/':
+ out = '/';
+ break;
+ case 'b':
+ out = '\b';
+ break;
+ case 'f':
+ out = '\f';
+ break;
+ case 'n':
+ out = '\n';
+ break;
+ case 'r':
+ out = '\r';
+ break;
+ case 't':
+ out = '\t';
+ break;
+ case 'u':
+ *p += 3; /* "u00" */
+ out = zbx_hex2num(**p) << 4;
+ out += zbx_hex2num(*(++*p));
+ break;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+ return '\0';
}
- return (size_t)(-1);
+ ++*p;
+
+ return out;
}
-static const char *zbx_json_decodeint(const char *p, char *string, size_t len)
+/******************************************************************************
+ * *
+ * Function: zbx_json_copy_string *
+ * *
+ * Purpose: copies json name/string value by omitting leading/trailing " and *
+ * converting escape sequences *
+ * *
+ * Parameters: p - [IN] a pointer to the next character in string *
+ * out - [OUT] the output buffer *
+ * size - [IN] the output buffer size *
+ * *
+ * Return value: A pointer to the next character in input string or NULL if *
+ * string copying failed. *
+ * *
+ ******************************************************************************/
+static const char *zbx_json_copy_string(const char *p, char *out, size_t size)
{
- char *o = string;
+ char *start = out;
+
+ p++;
- while ('\0' != *p) /* this should never happen */
+ while ('\0' != *p && out - start < size - 1)
{
- if ((*p < '0' || *p > '9') && *p != '-')
- {
- *o = '\0';
- return p;
- }
- else if ((size_t)(o - string) < len - 1/*'\0'*/)
+ switch (*p)
{
- *o++ = *p;
+ case '\\':
+ if ('\0' != (*out = zbx_json_decode_character(&p)))
+ out++;
+ break;
+ case '"':
+ *out = '\0';
+ return ++p;
+ default:
+ *out++ = *p++;
}
-
- p++;
}
return NULL;
}
-static const char *zbx_json_decodenull(const char *p)
-{
- if ('n' == p[0] && 'u' == p[1] && 'l' == p[2] && 'l' == p[3])
- return p + 4;
-
- return NULL;
-}
-
-static size_t zbx_json_value_size(const char *p, zbx_json_type_t jt)
+/******************************************************************************
+ * *
+ * Function: zbx_json_copy_value *
+ * *
+ * Purpose: copies json value *
+ * *
+ * Parameters: p - [IN] a pointer to the next character in string *
+ * len - [IN] the value length *
+ * out - [OUT] the output buffer *
+ * size - [IN] the output buffer size *
+ * *
+ * Return value: A pointer to the next character in input string or NULL if *
+ * string copying failed. *
+ * *
+ * Comments: String values are converted (leading/trailing " dropped and *
+ * escape sequences translated) while other values are simply *
+ * copied. *
+ * *
+ ******************************************************************************/
+static const char *zbx_json_copy_value(const char *p, size_t len, char *out, size_t size)
{
- switch (jt)
+ if (ZBX_JSON_TYPE_STRING == __zbx_json_type(p))
{
- case ZBX_JSON_TYPE_STRING:
- return zbx_json_string_size(p);
- case ZBX_JSON_TYPE_INT:
- return zbx_json_int_size(p);
- default:
- return (size_t)(-1);
+ if (NULL == zbx_json_copy_string(p, out, size))
+ return NULL;
}
+ else
+ zbx_strlcpy(out, p, MIN(size, len + 1));
+
+ return p + len;
}
-static const char *zbx_json_decodevalue(const char *p, char *string, size_t len, int *is_null)
+static const char *zbx_json_decodevalue(const char *p, char *string, size_t size, int *is_null)
{
+ size_t len;
+
switch (__zbx_json_type(p))
{
case ZBX_JSON_TYPE_STRING:
- if (NULL != is_null)
- *is_null = 0;
- return zbx_json_decodestring(p, string, len);
case ZBX_JSON_TYPE_INT:
if (NULL != is_null)
*is_null = 0;
- return zbx_json_decodeint(p, string, len);
+
+ if (0 == (len = json_parse_value(p, NULL)))
+ return NULL;
+
+ return zbx_json_copy_value(p, len, string, size);
case ZBX_JSON_TYPE_NULL:
if (NULL != is_null)
*is_null = 1;
@@ -723,28 +714,40 @@ static const char *zbx_json_decodevalue(const char *p, char *string, size_t len,
}
}
-static const char *zbx_json_decodevalue_dyn(const char *p, char **string, size_t *string_alloc)
+static const char *zbx_json_decodevalue_dyn(const char *p, char **string, size_t *string_alloc, int *is_null)
{
- zbx_json_type_t jt;
- size_t sz;
-
- jt = __zbx_json_type(p);
-
- if ((size_t)(-1) == (sz = zbx_json_value_size(p, jt)))
- return NULL;
+ size_t len;
- if (*string_alloc <= sz)
- {
- *string_alloc = sz + 1;
- *string = zbx_realloc(*string, *string_alloc);
- }
-
- switch (jt)
+ switch (__zbx_json_type(p))
{
case ZBX_JSON_TYPE_STRING:
- return zbx_json_decodestring(p, *string, *string_alloc);
case ZBX_JSON_TYPE_INT:
- return zbx_json_decodeint(p, *string, *string_alloc);
+ if (NULL != is_null)
+ *is_null = 0;
+
+ if (0 == (len = json_parse_value(p, NULL)))
+ return NULL;
+
+ if (*string_alloc <= len)
+ {
+ *string_alloc = len + 1;
+ *string = zbx_realloc(*string, *string_alloc);
+ }
+
+ return zbx_json_copy_value(p, len, *string, *string_alloc);
+ case ZBX_JSON_TYPE_NULL:
+ if (NULL != is_null)
+ *is_null = 1;
+
+ if (*string_alloc < 1)
+ {
+ *string_alloc = 1;
+ *string = zbx_realloc(*string, *string_alloc);
+ }
+
+ **string = '\0';
+
+ return zbx_json_decodenull(p);
default:
return NULL;
}
@@ -758,7 +761,7 @@ const char *zbx_json_pair_next(const struct zbx_json_parse *jp, const char *p, c
if (ZBX_JSON_TYPE_STRING != __zbx_json_type(p))
return NULL;
- if (NULL == (p = zbx_json_decodestring(p, name, len)))
+ if (NULL == (p = zbx_json_copy_string(p, name, len)))
return NULL;
SKIP_WHITESPACE(p);
@@ -815,6 +818,20 @@ const char *zbx_json_next_value(const struct zbx_json_parse *jp, const char *p,
/******************************************************************************
* *
+ * Function: zbx_json_next_value_dyn *
+ * *
+ ******************************************************************************/
+const char *zbx_json_next_value_dyn(const struct zbx_json_parse *jp, const char *p, char **string,
+ size_t *string_alloc, int *is_null)
+{
+ if (NULL == (p = zbx_json_next(jp, p)))
+ return NULL;
+
+ return zbx_json_decodevalue_dyn(p, string, string_alloc, is_null);
+}
+
+/******************************************************************************
+ * *
* Function: zbx_json_value_by_name *
* *
* Purpose: return value by pair name *
@@ -855,7 +872,7 @@ int zbx_json_value_by_name_dyn(const struct zbx_json_parse *jp, const char *name
if (NULL == (p = zbx_json_pair_by_name(jp, name)))
return FAIL;
- if (NULL == zbx_json_decodevalue_dyn(p, string, string_alloc))
+ if (NULL == zbx_json_decodevalue_dyn(p, string, string_alloc, NULL))
return FAIL;
return SUCCEED;
@@ -943,4 +960,3 @@ int zbx_json_count(const struct zbx_json_parse *jp)
return num;
}
-