mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-14 19:03:20 +00:00
Merge pull request #3634 from 94xhn/fix/json-hex-validation
Reject malformed input in mg_json_get_hex
This commit is contained in:
5 files changed
+29
-13
No files matched your search
+8
-5
@@ -5053,15 +5053,18 @@ char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) {
|
|||||||
char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
|
char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
int len = 0, off = mg_json_get(json, path, &len);
|
int len = 0, off = mg_json_get(json, path, &len);
|
||||||
if (off >= 0 && json.buf[off] == '"' && len > 1 &&
|
if (off >= 0 && json.buf[off] == '"' && len > 1 && (len - 2) % 2 == 0 &&
|
||||||
(result = (char *) mg_calloc(1, (size_t) len / 2)) != NULL) {
|
(result = (char *) mg_calloc(1, (size_t) len / 2)) != NULL) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len - 2; i += 2) {
|
for (i = 0; i < len - 2; i += 2) {
|
||||||
mg_str_to_num(mg_str_n(json.buf + off + 1 + i, 2), 16, &result[i >> 1],
|
if (!mg_str_to_num(mg_str_n(json.buf + off + 1 + i, 2), 16,
|
||||||
sizeof(uint8_t));
|
&result[i >> 1], sizeof(uint8_t))) break;
|
||||||
|
}
|
||||||
|
if (i < len - 2) mg_free(result), result = NULL;
|
||||||
|
if (result != NULL) {
|
||||||
|
result[len / 2 - 1] = '\0';
|
||||||
|
if (slen != NULL) *slen = len / 2 - 1;
|
||||||
}
|
}
|
||||||
result[len / 2 - 1] = '\0';
|
|
||||||
if (slen != NULL) *slen = len / 2 - 1;
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -4163,7 +4163,7 @@ char *mg_json_get_str(struct mg_str json, const char *path);
|
|||||||
|
|
||||||
// Decodes a hex-encoded JSON string at path into a heap-allocated byte array.
|
// Decodes a hex-encoded JSON string at path into a heap-allocated byte array.
|
||||||
// Sets *len to the decoded byte count. Caller must mg_free() the result.
|
// Sets *len to the decoded byte count. Caller must mg_free() the result.
|
||||||
// Returns NULL if not found or not a string.
|
// Returns NULL if not found, not a string, or not valid hexadecimal.
|
||||||
char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
|
char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
|
||||||
|
|
||||||
// Decodes a base64-encoded JSON string at path into a heap-allocated byte
|
// Decodes a base64-encoded JSON string at path into a heap-allocated byte
|
||||||
|
|||||||
+8
-5
@@ -363,15 +363,18 @@ char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) {
|
|||||||
char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
|
char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
int len = 0, off = mg_json_get(json, path, &len);
|
int len = 0, off = mg_json_get(json, path, &len);
|
||||||
if (off >= 0 && json.buf[off] == '"' && len > 1 &&
|
if (off >= 0 && json.buf[off] == '"' && len > 1 && (len - 2) % 2 == 0 &&
|
||||||
(result = (char *) mg_calloc(1, (size_t) len / 2)) != NULL) {
|
(result = (char *) mg_calloc(1, (size_t) len / 2)) != NULL) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len - 2; i += 2) {
|
for (i = 0; i < len - 2; i += 2) {
|
||||||
mg_str_to_num(mg_str_n(json.buf + off + 1 + i, 2), 16, &result[i >> 1],
|
if (!mg_str_to_num(mg_str_n(json.buf + off + 1 + i, 2), 16,
|
||||||
sizeof(uint8_t));
|
&result[i >> 1], sizeof(uint8_t))) break;
|
||||||
|
}
|
||||||
|
if (i < len - 2) mg_free(result), result = NULL;
|
||||||
|
if (result != NULL) {
|
||||||
|
result[len / 2 - 1] = '\0';
|
||||||
|
if (slen != NULL) *slen = len / 2 - 1;
|
||||||
}
|
}
|
||||||
result[len / 2 - 1] = '\0';
|
|
||||||
if (slen != NULL) *slen = len / 2 - 1;
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ char *mg_json_get_str(struct mg_str json, const char *path);
|
|||||||
|
|
||||||
// Decodes a hex-encoded JSON string at path into a heap-allocated byte array.
|
// Decodes a hex-encoded JSON string at path into a heap-allocated byte array.
|
||||||
// Sets *len to the decoded byte count. Caller must mg_free() the result.
|
// Sets *len to the decoded byte count. Caller must mg_free() the result.
|
||||||
// Returns NULL if not found or not a string.
|
// Returns NULL if not found, not a string, or not valid hexadecimal.
|
||||||
char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
|
char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
|
||||||
|
|
||||||
// Decodes a base64-encoded JSON string at path into a heap-allocated byte
|
// Decodes a base64-encoded JSON string at path into a heap-allocated byte
|
||||||
|
|||||||
+11
-1
@@ -3746,13 +3746,23 @@ static void test_json(void) {
|
|||||||
ASSERT(b == true);
|
ASSERT(b == true);
|
||||||
ASSERT(mg_json_get(json, "$.b[2]", &len) < 0);
|
ASSERT(mg_json_get(json, "$.b[2]", &len) < 0);
|
||||||
|
|
||||||
json = mg_str("[\"YWJj\", \"0100026869\"]");
|
json = mg_str("[\"YWJj\", \"0100026869\", \"\", \"abc\", \"0g\"]");
|
||||||
ASSERT((str = mg_json_get_b64(json, "$[0]", &len)) != NULL);
|
ASSERT((str = mg_json_get_b64(json, "$[0]", &len)) != NULL);
|
||||||
ASSERT(len == 3 && memcmp(str, "abc", (size_t) len) == 0);
|
ASSERT(len == 3 && memcmp(str, "abc", (size_t) len) == 0);
|
||||||
mg_free(str);
|
mg_free(str);
|
||||||
ASSERT((str = mg_json_get_hex(json, "$[1]", &len)) != NULL);
|
ASSERT((str = mg_json_get_hex(json, "$[1]", &len)) != NULL);
|
||||||
ASSERT(len == 5 && memcmp(str, "\x01\x00\x02hi", (size_t) len) == 0);
|
ASSERT(len == 5 && memcmp(str, "\x01\x00\x02hi", (size_t) len) == 0);
|
||||||
mg_free(str);
|
mg_free(str);
|
||||||
|
ASSERT((str = mg_json_get_hex(json, "$[2]", &len)) != NULL);
|
||||||
|
ASSERT(len == 0 && str[0] == '\0');
|
||||||
|
mg_free(str);
|
||||||
|
len = 42;
|
||||||
|
str = mg_json_get_hex(json, "$[3]", &len);
|
||||||
|
ASSERT(str == NULL && len == 42);
|
||||||
|
mg_free(str);
|
||||||
|
str = mg_json_get_hex(json, "$[4]", &len);
|
||||||
|
ASSERT(str == NULL && len == 42);
|
||||||
|
mg_free(str);
|
||||||
|
|
||||||
json = mg_str("{\"a\":[1,2,3], \"ab\": 2}");
|
json = mg_str("{\"a\":[1,2,3], \"ab\": 2}");
|
||||||
ASSERT(mg_json_get_long(json, "$.a[0]", -42) == 1);
|
ASSERT(mg_json_get_long(json, "$.a[0]", -42) == 1);
|
||||||
|
|||||||
Reference in new issue
Block a user