Skip to content

REST API: Fix object/array validation for JSON strings in GET requests (#64926)#11371

Open
liaisontw wants to merge 1 commit intoWordPress:trunkfrom
liaisontw:fix/64926-rest-api-json-get
Open

REST API: Fix object/array validation for JSON strings in GET requests (#64926)#11371
liaisontw wants to merge 1 commit intoWordPress:trunkfrom
liaisontw:fix/64926-rest-api-json-get

Conversation

@liaisontw
Copy link

@liaisontw liaisontw commented Mar 27, 2026

Description
Trac Ticket: https://core.trac.wordpress.org/ticket/64926

This PR addresses #64926, where REST API GET requests fail validation when parameters defined as object or array are passed as JSON-encoded strings (e.g., via JSON.stringify).

The Problem
Currently, rest_validate_value_from_schema() receives these parameters as raw strings from $_GET. Since the schema expects an object or array, it triggers a rest_invalid_type error (400 Bad Request) before any sanitization or decoding can occur. While POST requests handle this via parse_json_params(), no equivalent coercion exists for query-string parameters.

The Fix
This PR introduces JSON coercion in both rest_validate_value_from_schema() and rest_sanitize_value_from_schema().

If the schema expects a structured type but receives a string, it attempts to json_decode().

Uses json_last_error() === JSON_ERROR_NONE to ensure only valid JSON is coerced, maintaining safety for regular strings.

Supports multi-type schemas (e.g., ['string', 'object']).

No changes to function signatures, ensuring backward compatibility.

How to Test
Register a test endpoint with an object type parameter:

PHP
register_rest_route( 'my-test/v1', '/schema-test', array(
'methods' => 'GET',
'callback' => function( $request ) {
return array( 'success' => true, 'data' => $request->get_param( 'config' ) );
},
'args' => array(
'config' => array( 'type' => 'object' ),
),
) );
Test Case A: Valid JSON Object

URL: /wp-json/my-test/v1/schema-test?config={"id":123,"name":"Gemini"}

Expected Result: {"success":true,"data":{"id":123,"name":"Gemini"}} (Integers preserved).

Test Case B: Empty Object

URL: /wp-json/my-test/v1/schema-test?config={}

Expected Result: {"success":true,"data":[]} (PHP decodes empty JSON object as array).

Test Case C: Invalid JSON (Safety Check)

URL: /wp-json/my-test/v1/schema-test?config={id:123}

Expected Result: 400 Bad Request (Correctly rejected because it's not valid JSON and doesn't match type object).

Screenshots/Logs
Tested in a local WordPress development environment.

Before Patch: Returns rest_invalid_type error for all JSON string inputs in GET.

After Patch: Successfully decodes and validates structured data while maintaining strictness for invalid JSON.

Types of changes
[x] Bug fix (non-breaking change which fixes an issue)

[ ] New feature (non-breaking change which adds functionality)

[ ] Performance improvement

@github-actions
Copy link

github-actions bot commented Mar 27, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props liaison, dsmy.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions
Copy link

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@liaisontw liaisontw force-pushed the fix/64926-rest-api-json-get branch 3 times, most recently from 99a47e0 to 90e693a Compare March 27, 2026 05:11
….This commit aligns GET parameter handling with POST requests by allowingJSON-encoded strings to pass 'object' and 'array' validation andsanitization.- Added JSON coercion in rest_validate_value_from_schema().- Added JSON coercion in rest_sanitize_value_from_schema().- Supports multi-type schemas and uses json_last_error() for safety.Fixes #64926
@liaisontw liaisontw force-pushed the fix/64926-rest-api-json-get branch from 90e693a to ec06d13 Compare March 27, 2026 05:13
@liaisontw liaisontw closed this Mar 27, 2026
@liaisontw liaisontw reopened this Mar 27, 2026
@dsmy
Copy link

dsmy commented Mar 27, 2026

Appreciate you taking the time for this @liaisontw

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants