Skip to content

Commit

Permalink
Merge branch 'v2.x/rc' into v2.x/staging
Browse files Browse the repository at this point in the history
  • Loading branch information
James Struga committed Sep 18, 2024
2 parents cf8c51d + bfef848 commit 7cc275c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
49 changes: 47 additions & 2 deletions c/jsonschema.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,27 @@ static JSValueSpec *resolveRef(JsonValidator *validator, ValidityException *pend
static VResult validateJSONSimple(JsonValidator *validator,
Json *value, JSValueSpec *valueSpec, int depth, EvalSet *evalSetList){
if (jsonIsNull(value)){
return validateType(validator,JSTYPE_NULL,valueSpec,depth+1);
VResult typeResult = validateType(validator,JSTYPE_NULL,valueSpec,depth+1);
if (vStatusValid(typeResult.status)) {
return typeResult;
} else if (validator->allowStringToBeNull) {
// FIXME: Some users were relying upon a bug we fixed, where an empty value would be treated as a string.
// TODO: Remove this in v3, we should not keep this bug compatability forever.
if (((1 << JSTYPE_STRING) & valueSpec->typeMask) != 0){
Json *emptyStringJson = (Json*)safeMalloc(sizeof(Json), "Empty String JSON");
emptyStringJson->type = JSON_TYPE_STRING;
char emptyString[1] = {0};
emptyStringJson->data.string = emptyString;
// Check if schema is okay with an "empty string" as the previous bug had null be empty string.
VResult stringResult = validateJSONString(validator,emptyStringJson,valueSpec,depth+1);
safeFree((char*)emptyStringJson, sizeof(Json));
return stringResult;
} else{
return simpleFailure(validator, "string cannot be null for %s\n", validatorAccessPath(validator));
}
} else {
return typeResult;
}
} else if (jsonIsBoolean(value)){
return validateType(validator,JSTYPE_BOOLEAN,valueSpec,depth+1);
} else if (jsonIsObject(value)){
Expand Down Expand Up @@ -1306,14 +1326,34 @@ static VResult validateJSON(JsonValidator *validator,
/* As we go through the valid enum values, record them in comma separated
* form for displaying at the tail end of the error message.
*/

bool nullToString = false;
Json *emptyStringJson;
if (jsonIsNull(value)) {
VResult typeResult = validateType(validator,JSTYPE_NULL,valueSpec,depth+1);
if ((!vStatusValid(typeResult.status)) && (validator->allowStringToBeNull)) {
// FIXME: Some users were relying upon a bug we fixed, where an empty value would be treated as a string.
// TODO: Remove this in v3, we should not keep this bug compatability forever.
if (((1 << JSTYPE_STRING) & valueSpec->typeMask) != 0){
emptyStringJson = (Json*)safeMalloc(sizeof(Json), "Empty String JSON");
emptyStringJson->type = JSON_TYPE_STRING;
char emptyString[1] = {0};
emptyStringJson->data.string = emptyString;
nullToString = true;
}
}
}

unsigned int validValuesMaxSize = (valueSpec->enumeratedValuesCount * (sizeof(Json*) + 3)) + 1;
char *validValues = SLHAlloc(validator->evalHeap, validValuesMaxSize);
if (validValues) {
memset(validValues, 0, validValuesMaxSize);
}

Json *whichValue = nullToString == true ? emptyStringJson : value;
for (int ee=0; ee<valueSpec->enumeratedValuesCount; ee++){
Json *enumValue = valueSpec->enumeratedValues[ee];
if (jsonEquals(value,enumValue)){
if (jsonEquals(whichValue,enumValue)){
matched = true;
break;
}
Expand All @@ -1337,6 +1377,9 @@ static VResult validateJSON(JsonValidator *validator,
strcat(validValues, ", ");
}
}
if (nullToString) {
safeFree((char*)emptyStringJson, sizeof(Json));
}
if (!matched){
if (validValues && strlen(validValues) > 0) {
return simpleFailure(validator,"no matching enum value at %s; expecting one of values '[%s]' of type '%s'",
Expand Down Expand Up @@ -1420,6 +1463,8 @@ static VResult validateJSON(JsonValidator *validator,
int jsonValidateSchema(JsonValidator *validator, Json *value, JsonSchema *topSchema,
JsonSchema **otherSchemas, int otherSchemaCount){
int result = 0;
validator->allowStringToBeNull = true;

if (setjmp(validator->recoveryData) == 0) { /* normal execution */
validator->topSchema = topSchema;
validator->otherSchemas = otherSchemas;
Expand Down
1 change: 1 addition & 0 deletions h/jsonschema.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ typedef struct JsonValidator_tag {
int fileRegexError;
jmp_buf recoveryData;
ShortLivedHeap *evalHeap;
bool allowStringToBeNull;
} JsonValidator;

#define JSON_SCHEMA_DRAFT_4 400
Expand Down

0 comments on commit 7cc275c

Please sign in to comment.