Project

General

Profile

Actions

Bug #66581

closed

Extbase - JsonView: wrong key encoding in array

Added by Thilo Schumann about 9 years ago. Updated about 1 year ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
Extbase
Target version:
-
Start date:
2015-04-24
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
6.2
PHP Version:
Tags:
Complexity:
Is Regression:
No
Sprint Focus:

Description

If the array key is of type string, then the PHP function json_encode converts it to named objects instead of an array.
Extbase internal reference identifiers are encoded of type string instead of integer.

The bug is here in case of '_descendAll' https://github.com/TYPO3/TYPO3.CMS/blob/master/typo3/sysext/extbase/Classes/Mvc/View/JsonView.php#L255

FIX: convert the key to integer

Change from:

$array[$key] = $this->transformValue($element, $configuration['_descendAll']);

to:

$array[hexdec($key)] = $this->transformValue($element, $configuration['_descendAll']);

Actions #1

Updated by Andreas Allacher about 9 years ago

Is this abut e.g. objects in ObjectStorage?
If so, I think it might be best to check if there is a toArray method and call that beforehand because that way object storage converts itself to a numerical array which would be more correct.
ObjectStorage otherwise uses spl_object_hash as key.

Just removing the key itself is wrong because there can be other ArrayAccess objects that use "good" string values as keys which should not be "removed".

Actions #2

Updated by Andreas Allacher about 9 years ago

Maybe even better would be an interface for objectstorage that needs toArray that way it could be done with instanceof and would not be used classes that do something unexpected with toArray

Actions #3

Updated by Thilo Schumann almost 9 years ago

To explain it a bit more:

I have setup in "Extension Builder" my own Ext. That Ext is very simple and something like: a list of companies, which has a 1:n relation to a list of daughters/sub-companies. Extbase itself generates internally an hexadecimal identifier for that. That identifier is encoded as a string value in Extbase instead of an integer value.

Then I want to export it in a JSON.

The PHP function json_encode() seems to encode an array with integer values as keys as an array, but an array with string values as keys are exported as named objects. As this "string" is only an internal reference of Extbase it makes no sense to export in JSON. So the key must be converted to integer before using the PHP function json_encode().

The above fix has a flaw, because hexdec() converts integer values to string. (Is here PHP broken? WTF!)

I changed the fix to:

                    if (is_int($key))
                        $array[$key] = $this->transformValue($element, $configuration['_descendAll']);
                    else
                      $array[hexdec($key)] = $this->transformValue($element, $configuration['_descendAll']);

Actions #4

Updated by Andreas Allacher almost 9 years ago

Yes, that is true for ObjectStorage.
However, that might not be the case for other objects with ArrayAccess and just because most of the time extbase ArrayAccess objects will be used, doesn't mean that will be the case all the time.
So one would have to specifically handle ObjectStorage (and other corresponding) objects here.

Also the same loop is used for arrays which if they are not integer based most likely have important information in the keys.

The easist solution would be to check if the value has a method toArray and if so call that one. Or maybe even better create a corresponding interface (that requires toArray) for ObjectStorage and so on and implement it.
That way such objects (e.g. ObjectStorage) will be converted to an array with integer keys as index.

Regarding hexdec: I don't think it is a good idea to use hexdec anyway because according to php.net it can also return float values.

If one wants to ignore the key value which as mentioned might not be the case all the time, I would just use $array[] = ....
that way it will be added to an integer based array 0,1,.... which would be enough

Actions #5

Updated by Riccardo De Contardi about 8 years ago

  • Category set to Extbase
Actions #6

Updated by Markus Klein over 7 years ago

  • Status changed from New to Needs Feedback

Still valid?

Actions #7

Updated by Alexander Opitz over 7 years ago

  • Status changed from Needs Feedback to Closed

No feedback within the last 90 days => closing this issue.

If you think that this is the wrong decision or experience this issue again, then please write to the mailing list typo3.teams.bugs with issue number and an explanation or open a new ticket and add a relation to this ticket number.

Actions #8

Updated by Markus Klein over 1 year ago

  • Status changed from Closed to Accepted

This is still the case even in v12.

At least the default ObjectStorage should work out of the box in the expected way.
(we have a dedicated JsonView in every extension, just because of this bug)

Actions #9

Updated by Gerrit Code Review over 1 year ago

  • Status changed from Accepted to Under Review

Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/77361

Actions #10

Updated by Gerrit Code Review over 1 year ago

Patch set 2 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/77361

Actions #11

Updated by Markus Klein about 1 year ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100
Actions #12

Updated by Benni Mack about 1 year ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF