diff --git a/CHANGES.md b/CHANGES.md index ec7350113..199a09958 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -43,6 +43,8 @@ v3.0.4 - YYYY-MM-DD - Fixed `ippValidateAttribute` not returning `false` for too-long URIs. - Fixed a memory leak in `httpGetSecurity` when using GNU TLS. - Fixed a memory leak in `cupsJWTImportString`. +- Fixed a buffer overflow in `cupsJSONExportString` when exporting a child + node. - Fixed a bug in `cupsJWTExportString` with JSON output. diff --git a/cups/json.c b/cups/json.c index 1a3199be7..e88f87a22 100644 --- a/cups/json.c +++ b/cups/json.c @@ -250,7 +250,7 @@ cupsJSONExportString(cups_json_t *json) // I - JSON root node while (current) { - if (current->parent && current->parent->value.child != current) + if (current != json && current->parent && current->parent->value.child != current) length ++; // Comma or colon separator switch (current->type) @@ -295,6 +295,11 @@ cupsJSONExportString(cups_json_t *json) // I - JSON root node // Descend current = current->value.child; } + else if (current == json) + { + // Done with the node being exported... + current = NULL; + } else if (current->sibling) { // Visit sibling @@ -306,7 +311,12 @@ cupsJSONExportString(cups_json_t *json) // I - JSON root node current = current->parent; while (current) { - if (current->sibling) + if (current == json) + { + current = NULL; + break; + } + else if (current->sibling) { current = current->sibling; break; @@ -335,7 +345,7 @@ cupsJSONExportString(cups_json_t *json) // I - JSON root node while (current) { - if (current->parent && current->parent->value.child != current) + if (current != json && current->parent && current->parent->value.child != current) { // Add separator if (current->type == CUPS_JTYPE_KEY || current->parent->type == CUPS_JTYPE_ARRAY) @@ -443,7 +453,12 @@ cupsJSONExportString(cups_json_t *json) // I - JSON root node else if (current->type == CUPS_JTYPE_OBJECT) *ptr++ = '}'; - if (current->sibling) + if (current == json) + { + // Done with the node being exported... + current = NULL; + } + else if (current->sibling) { // Visit sibling current = current->sibling; @@ -459,7 +474,12 @@ cupsJSONExportString(cups_json_t *json) // I - JSON root node else if (current->type == CUPS_JTYPE_OBJECT) *ptr++ = '}'; - if (current->sibling) + if (current == json) + { + current = NULL; + break; + } + else if (current->sibling) { current = current->sibling; break; diff --git a/cups/testjson.c b/cups/testjson.c index bc3b376ab..8ea24d674 100644 --- a/cups/testjson.c +++ b/cups/testjson.c @@ -267,6 +267,24 @@ main(int argc, // I - Number of command-line arguments testEndMessage(false, "unable to load Unicode surrogate escapes"); } + testBegin("cupsJSONExportString(child object)"); + if ((json = cupsJSONImportString("{\"a\":{\"b\":[1,2],\"c\":{\"d\":true}},\"e\":null}")) != NULL) + { + if ((s = cupsJSONExportString(cupsJSONFind(json, "a"))) == NULL) + testEndMessage(false, "%s", cupsGetErrorString()); + else if (strcmp(s, "{\"b\":[1,2],\"c\":{\"d\":true}}")) + testEndMessage(false, "got '%s'", s); + else + testEndMessage(true, "%s", s); + + free(s); + cupsJSONDelete(json); + } + else + { + testEndMessage(false, "%s", cupsGetErrorString()); + } + testBegin("cupsJSONImportURL('https://accounts.google.com/.well-known/openid-configuration', no last modified)"); json = cupsJSONImportURL("https://accounts.google.com/.well-known/openid-configuration", &last_modified);