#53936 closed defect (bug) (fixed)
Output of serialize_block_attributes does not match equivalent Gutenberg function
Reported by: | kevinfodness | Owned by: | desrosj |
---|---|---|---|
Milestone: | 5.8.1 | Priority: | normal |
Severity: | normal | Version: | 5.3.1 |
Component: | Editor | Keywords: | has-patch has-unit-tests commit fixed-major |
Focuses: | Cc: |
Description
In wp-includes/blocks.php
, the serialize_block_attributes function runs json_encode
with no options, which results in encoding all unicode elements and slashes. This behavior differs from Gutenberg's attribute serializer, which uses JSON.stringify, for which the default behavior does not encode slashes or unicode characters. In order to ensure that the two attribute serialization functions return the same output, I recommend using the options JSON_UNESCAPED_UNICODE
and JSON_UNESCAPED_SLASHES
in the PHP function.
This example illustrates the differences in output between the two functions:
<?php serialize_block_attributes( [ 'product' => 'Mike & Ike: €1.00 / 3 for €2.00' ] ); // {"product":"Mike \u0026 Ike: \u20ac1.00 \/ 3 for \u20ac2.00"}
Versus JavaScript:
serializeAttributes({ product: 'Mike & Ike: €1.00 / 3 for €2.00' }); // {"product":"Mike \u0026 Ike: €1.00 / 3 for €2.00"}
In the PHP example, the forward slash and the Euro symbol are both escaped, but in JavaScript, they aren't.
If we modify the flags in the serialize_block_attributes
as follows:
$encoded_attributes = json_encode( $block_attributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
Then the output matches what we get from the JavaScript function.
I'll get working on a patch that both exposes this issue via a unit test and resolves it in the manner I proposed above, and I'll attach it here when I'm done.
Related: Is there a reason why we are using json_encode
here rather than wp_json_encode
? As near as I can tell, this is the only location in WordPress core source code that uses json_encode
other than the wp_json_encode
function itself. Assuming this is in error, I'll make that change in my patch as well.
Change History (9)
#1
in reply to:
↑ description
@
3 years ago
- Component changed from General to Editor
This ticket was mentioned in PR #1594 on WordPress/wordpress-develop by kevinfodness.
3 years ago
#2
- Keywords has-patch has-unit-tests added
The block attribute serialization function in PHP does not produce equivalent output to the JavaScript function in the Gutenberg codebase. Specifically, unicode characters and slashes are escaped in PHP whereas they are not in JavaScript. This update exposes the bug via a unit test and fixes it in the serialization function. Additionally, it replaces json_encode
with wp_json_encode
.
Trac ticket: https://core.trac.wordpress.org/ticket/53936
#3
@
3 years ago
- Milestone changed from Awaiting Review to 5.8.1
This looks like something that could be included in 5.8.1. Moving to the milestone for consideration.
#4
@
3 years ago
- Keywords commit added
Thanks for this fix, @kevinfodness! I discussed this briefly with @TimothyBlynJacobs in Slack, and he recalled that this reminded him of #40560. But, we arrived at the decision that it probably makes sense to land this.
#6
@
3 years ago
- Owner set to desrosj
- Resolution set to fixed
- Status changed from new to closed
In 51674:
#7
@
3 years ago
- Keywords fixed-major added
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening to backport.
kevinfodness commented on PR #1594:
3 years ago
#9
This was merged via svn, so I'm closing the PR here.
Hi there, welcome to WordPress Trac! Thanks for a detailed bug report.
Replying to kevinfodness:
Good catch, this seems like an oversight. Per [30055] / #28786, any
json_encode()
calls in core should indeed be converted towp_json_encode()
, as the former can fail if the data contains any non UTF-8 characters.