Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR #25490

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

Merged
merged 1 commit into from
Jan 10, 2018

Conversation

diversantvlz
Copy link
Contributor

@diversantvlz diversantvlz commented Dec 13, 2017

Q A
Branch? 2.7
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets no
License MIT
Doc PR no

Php function json_encode/decode with option JSON_PARTIAL_OUTPUT_ON_ERROR return result on error, but if have is error json_last_error() always return error code even if there is a result and it is not false. Because of this is impossible set JSON_PARTIAL_OUTPUT_ON_ERROR option across variable $context.

Current fix solves this problem.

Verification on the false is completely correct, since json_encode / decode returns false only on error if not set JSON_PARTIAL_OUTPUT_ON_ERROR option.

Such have a problem e.g when encoding data is not utf-8 (emoji from facebook).

@dunglas
Copy link
Member

dunglas commented Dec 13, 2017

Could you add some unit tests please?

@nicolas-grekas nicolas-grekas changed the title [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT… [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR Dec 18, 2017
@nicolas-grekas nicolas-grekas added this to the 2.7 milestone Dec 18, 2017
throw new UnexpectedValueException(JsonEncoder::getLastErrorMessage());
if (false === $decodedData) {
$this->lastError = json_last_error();
throw new UnexpectedValueException(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be on one line according to our CS policy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -95,8 +95,11 @@ public function decode($data, $format, array $context = array())
$decodedData = json_decode($data, $associative, $recursionDepth);
}

if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(JsonEncoder::getLastErrorMessage());
if (false === $decodedData) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$decodedData can be false without it being an error if you decode the "false" string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, json_decode('false') return string 'false', not boolean false. false !== 'false'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diversantvlz you should try running it :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, like this?

@Simperfit
Copy link
Contributor

@diversantvlz Could you please add some unit test ?

@@ -95,8 +95,8 @@ public function decode($data, $format, array $context = array())
$decodedData = json_decode($data, $associative, $recursionDepth);
}

if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(JsonEncoder::getLastErrorMessage());
if (JSON_ERROR_NONE !== $this->lastError = json_last_error() and false === $decodedData) {
Copy link
Member

@dunglas dunglas Dec 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use && instead of and (it doesn't have the same priority).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact using && will break precedence, but it should still be used, so that both operands should be swapped

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@nicolas-grekas
Copy link
Member

Shouldn't we also check if the JSON_PARTIAL_OUTPUT_ON_ERROR flag is set?
This needs a test case for sure :)
Also, why removing the call to JsonEncoder::getLastErrorMessage()?

@diversantvlz
Copy link
Contributor Author

Options argument in json_encode is a bit mask. To understand if a flag is installed, additional calculations must be made.

@Simperfit
Copy link
Contributor

@diversantvlz Do you want me to help you adding a test ?

@diversantvlz
Copy link
Contributor Author

@Simperfit Yes, why not. I would be thankful. I do not have enough time for this task, i can do it the next week.
It would be nice to test for something like:

//for decode
json_decode('false') === false && json_last_error() === JSON_ERROR_NONE;

//for encode
$arr = array(
   'utf8' => 'Hello World!', 
   'notUtf8' => "\xb0\xd0\xb5\xd0"
);

json_encode($arr) === false && json_last_error() === JSON_ERROR_UTF8;
json_encode($arr , JSON_PARTIAL_OUTPUT_ON_ERROR)  === '{"utf8":  "Hello World!", "notUtf8": null}' &&  json_last_error() === JSON_ERROR_UTF8;

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diversantvlz FYI I pushed on your fork, with a test case, and reverting the change on JsonDecode since it cannot happen there (please provide a test case if you don't agree.)

@diversantvlz
Copy link
Contributor Author

@nicolas-grekas @dunglas Review test case please.

@nicolas-grekas nicolas-grekas force-pushed the 2.7 branch 3 times, most recently from 3e75b6e to 3fb8c58 Compare January 10, 2018 08:40
@nicolas-grekas
Copy link
Member

Thanks @diversantvlz FYI, I reverted the change on JsonDecode because it just shouldn't change, partial jsons is only a feature of JsonEncode.
I also fixed the code-style in the tests, and reverted a few other unrelated changes (like the not calling JsonEncoder::getLastErrorMessage() but constructing the message inline? - I guess these must be some bad merge/rebase.)

@nicolas-grekas
Copy link
Member

Logic now fixed to work as expected on PHP 5.4 & 5.3.
PR ready.

Status: reviewed

@nicolas-grekas
Copy link
Member

Thank you @diversantvlz.

@nicolas-grekas nicolas-grekas merged commit e7e410b into symfony:2.7 Jan 10, 2018
nicolas-grekas added a commit that referenced this pull request Jan 10, 2018
…TIAL_OUTPUT_ON_ERROR (diversantvlz)

This PR was merged into the 2.7 branch.

Discussion
----------

[Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass?   | yes
| Fixed tickets | no
| License       | MIT
| Doc PR        | no

<!--
- Bug fixes must be submitted against the lowest branch where they apply
  (lowest branches are regularly merged to upper ones so they get the fixes too).
- Features and deprecations must be submitted against the master branch.
- Replace this comment by a description of what your PR is solving.
-->

Php function json_encode/decode with option JSON_PARTIAL_OUTPUT_ON_ERROR  return result on error, but if have is error json_last_error() always return error code even if there is a result and it is not false. Because of this is impossible set JSON_PARTIAL_OUTPUT_ON_ERROR option across variable $context.

Current fix solves this problem.

Verification on the false is completely correct, since json_encode / decode returns false only on error if not set JSON_PARTIAL_OUTPUT_ON_ERROR option.

Such have a problem e.g when encoding data is not utf-8 (emoji from facebook).

Commits
-------

e7e410b [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants