Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing code in staging #485

Merged
merged 18 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading