Support from Acquia helps fund testing for Drupal Acquia logo

Comments

gabesullice created an issue. See original summary.

gabesullice’s picture

Title: JSON:API link keys can overwrite each other » JSON:API link keys can collide
FileSize
947 bytes

Rough fix.

larowlan’s picture

Status: Active » Needs review
Issue tags: +Bug Smash Initiative, +Needs tests

This looks good, we'll need some tests to go with it however

gabesullice’s picture

gabesullice’s picture

gabesullice’s picture

gabesullice’s picture

Issue summary: View changes

Status: Needs review » Needs work

The last submitted patch, 6: drupal-jsonapi_link_key_collisions-3175884-6.patch, failed testing. View results

gabesullice’s picture

Status: Needs work » Needs review

Unrelated fail, I think

mglaman’s picture

This looks good and ensure normalization varies based on link attributes. I just have one nit

+++ b/core/modules/jsonapi/src/Normalizer/LinkCollectionNormalizer.php
@@ -94,7 +94,13 @@ protected function hashByHref(Link $link) {
+    $params = [
+      'href' => $link->getHref(),
+    ] + $link->getTargetAttributes();
+    foreach ($params as $name => $value) {
...
+    }
+    return substr(str_replace(['-', '_'], '', Crypt::hashBase64($this->hashSalt . implode(';', array_values($params)))), 0, 7);

If we're running array_values why not build $params as a non-associative array?

$params = [
   'href=' . $link->getHref();
]
foreach ($params as $name => $value) {
  $params[] = sprintf('%s="%s"', $name, implode(' ', (array) $value));
}

Then it's just implode(';', $params)

Uber nit.

juagarc4’s picture

It looks good for me too. I have tested it successfully.

@mglaman I like your proposal about non-associative array but I don't understand why you removed the part where the link attributes are joined => "+ $link->getTargetAttributes()". I suppose it's a mistake.

Although I like to maintain things as simple as possible an I like your proposal about non-associative array, I think in this case make sense to use an associative array.
With a non-associative array you can introduce duplicates in $params array provided by $link->getTargetAttributes(). The use of an associative array will avoid this duplicates.

On the other hand, If the duplicates are not a problem an we want to use a non-associative array, the code would be:

$param_values = [
   'href=' . $link->getHref();
] + $link->getTargetAttributes()

foreach ($params_values as $value) {
  $params[] = sprintf("%s", implode(' ', (array) $value));
}

Otherwise we will have a wrong output because sprintf() takes the index as part of the string.
Moreover we need to use different names for $params or we will get duplicated values.

gabesullice’s picture

Thanks for the reviews! I like the suggestion to get rid of array_values().

@juagarc4, I'm not worried about duplicates because getTargetAttributes can't return duplicates—it's using an associative array internally. I kept the strings with semi-colons and the parameter names in place because then the generated string matches the standard for link parameters in Link headers. That isn't necessary but it's a nice touch I think :)

mglaman’s picture

Status: Needs review » Reviewed & tested by the community

💥 Looks great to me. RTBC. I know the array_values thing was a nit, but I like to remove extra array structuring and destructing if possible.

alexpott’s picture

Title: JSON:API link keys can collide » [backport] JSON:API link keys can collide

Committed e239d3e and pushed to 9.2.x. Thanks!

  • alexpott committed e239d3e on 9.2.x
    Issue #3175884 by gabesullice, mglaman, juagarc4: JSON:API link keys can...
Wim Leers’s picture

Nice catch! 🤯

  • alexpott committed e852eaf on 9.2.x
    Revert "Issue #3175884 by gabesullice, mglaman, juagarc4: JSON:API link...
alexpott’s picture

Title: [backport] JSON:API link keys can collide » JSON:API link keys can collide
Status: Reviewed & tested by the community » Needs work

@catch pointed out that a comment might be useful in to explain what the code is doing. This made me realise that the method docs are no longer correct...

  /**
   * Hashes a link by its href.
   *
   * @param \Drupal\jsonapi\JsonApiResource\Link $link
   *   A link to be hashed.
   *
   * @return string
   *   A 7 character alphanumeric hash.
   */

I think this needs updating to be more complete.

gabesullice’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
2.49 KB
5.06 KB

🙈 good catch!

Taking the liberty to go straight to RTBC since this only adds comments.

alexpott credited catch.

alexpott’s picture

Version: 9.0.x-dev » 9.1.x-dev
Status: Reviewed & tested by the community » Fixed

Committed and pushed 99b763a12a to 9.2.x and 849ca9b597 to 9.1.x. Thanks!

Backported to 9.1.x as this is a straight up bug fix.

  • alexpott committed 99b763a on 9.2.x
    Issue #3175884 by gabesullice, mglaman, juagarc4, catch: JSON:API link...

  • alexpott committed 849ca9b on 9.1.x
    Issue #3175884 by gabesullice, mglaman, juagarc4, catch: JSON:API link...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.