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

patterProperties with int key #780

Closed
sakarikl opened this issue Feb 5, 2025 · 5 comments
Closed

patterProperties with int key #780

sakarikl opened this issue Feb 5, 2025 · 5 comments

Comments

@sakarikl
Copy link

sakarikl commented Feb 5, 2025

preg_match(): Argument #2 ($subject) must be of type string, int given

string cast seems to be missing from src/JsonSchema/Constraints/ObjectConstraint.php@69

'patternProperties' => [ '^[0-9]+$' => [ 'type' => 'object', 'additionalProperties' => false,

@DannyvdSluijs
Copy link
Collaborator

@sakarikl thank for the report. Could you also add some reproduction steps e.g. a schema and json value?

@sakarikl
Copy link
Author

sakarikl commented Feb 6, 2025

$json = '{
"10": 123,
"101": 5
}
';

$schema = [
    'type' => 'object',
    'patternProperties' => [
        '^[0-9]+$' => ['type' => 'integer']
    ],
];

$data = json_decode($json, true);
$validator = new JsonSchema\Validator();
$validator->validate(
    $data,
    $schema,
    Constraint::CHECK_MODE_COERCE_TYPES | Constraint::CHECK_MODE_APPLY_DEFAULTS | Constraint::CHECK_MODE_EXCEPTIONS | Constraint::CHECK_MODE_TYPE_CAST,
);

$validator->isValid();

This reproduces error. Sorry meant to put this to original post :)

@DannyvdSluijs
Copy link
Collaborator

DannyvdSluijs commented Feb 7, 2025

Based on your code I'm getting the same error. What I noticed however is the line $data = json_decode($json, true); where the boolean true turns the return value into an associative array, which is something that doesn't exist in JSON.

This causes issues down the line like with the ObjectConstraint. A fix for you would be to remove the boolean true and get the stdClass returned instead of the associative array. The same applies to the schema and object would better to pass this as an object.

My suggested code would be:

$data = json_decode(
<<<'JSON'
{
  "10": 123,
  "101": 5 
}
JSON
);

$schema = json_decode(<<<'JSON'
{
  "type": "object",
  "patternProperties": {
    "^[0-9]+$": {
      "type": "integer"
    }
  }
}
JSON
);

$validator = new Validator();
$validator->validate(
    $data,
    $schema,
    Constraint::CHECK_MODE_COERCE_TYPES | Constraint::CHECK_MODE_APPLY_DEFAULTS | Constraint::CHECK_MODE_EXCEPTIONS | Constraint::CHECK_MODE_TYPE_CAST,
);

$validator->isValid();

if ($validator->isValid()) {
    echo "The supplied JSON validates against the schema.\n";
} else {
    echo "JSON does not validate. Violations:\n";
    foreach ($validator->getErrors() as $error) {
        printf("[%s] %s\n", $error['property'], $error['message']);
    }
}

@DannyvdSluijs
Copy link
Collaborator

Seeing the thumbs up as a answer to your problem. Closing the issue for now, feel free to reopen if needed,

@sakarikl
Copy link
Author

I can't use that workaround but I can live with that by making a patch for myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants