Malformed UTF-8 characters in PaginatedModelsLoader
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 3.5k
- Forks
- 468
- Avg merge
- 3h 9m
- Merged PRs (30d)
- 2
Description
Describe the bug
https://github.com/nuwave/lighthouse/pull/2540 added a json_encode call at https://github.com/SOERF/lighthouse/blob/master/src/Execution/ModelsLoader/PaginatedModelsLoader.php#L89 to compare models rather than toJson, which was changed to encoding the raw original values in https://github.com/nuwave/lighthouse/pull/2550 to avoid some casted values not being able to json_encode. However, some raw values cannot be passed to json_encode either, like binary UUID representations as used by https://github.com/michaeldyrynda/laravel-model-uuid. The raw value is a string in PHP but it is not valid UTF-8, so json_encode fails with the JSON_ERROR_UTF8 error.
I am happy to assist with a PR here though I don't think this has an obvious solution so I wanted to discuss in an Issue before I went down that path.
Expected behavior/Solution
Comparison should complete without error while still comparing all values as needed.
- This could be worked around simply by passing the JSON_INVALID_UTF8_IGNORE or JSON_INVALID_UTF8_SUBSTITUTE flags to json_encode, but this likely has poor side effects I'm not currently thinking about by effectively hiding these values from the comparison.
- Ideally the comparison should correctly compare the full attributes as intended without failing on non-encodable values either pre- or post-cast.
Steps to reproduce
- Define a has-many relationship between two models with a column using the Laravel Model UUID library (or similar non-UTF8 strings)
- Return the relationship in a GraphQL field using the
@hasMany(type: PAGINATOR)directive - Attempt to load the field, see the error during the
json_encodecall
Output/Logs
Safe\Exceptions\JsonException: Malformed UTF-8 characters, possibly incorrectly encoded in /.../vendor/thecodingmachine/safe/lib/Exceptions/JsonException.php:9
Stack trace:
#0 /.../vendor/thecodingmachine/safe/generated/8.1/json.php(20): Safe\Exceptions\JsonException::createFromPhpError()
#1 /.../vendor/nuwave/lighthouse/src/Execution/ModelsLoader/PaginatedModelsLoader.php(89): Safe\json_encode(Array)
Lighthouse Version
v6.70.1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/Execution/ModelsLoader/PaginatedModelsLoader.php around line 89, where Safe\json_encode compares models. Reproduce the failure through a GraphQL field using @hasMany(type: PAGINATOR) with a non-UTF-8 value such as a binary UUID. Done means pagination comparison completes without an encoding error while still comparing the full attributes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, laravel, php
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100