Verified Commit 4172ec42 authored by Jess's avatar Jess
Browse files

fix: #3609975 UrlHelper::uncompressQueryParameter() should set a gzuncompress() character limit

By: catch
By: poker10
By: greggles
By: prudloff
By: mcdruid
By: briantbailey
By: pranjali45
By: brandonlira
By: xjm
(cherry picked from commit 1ea1e55d)
parent 32e03f06
Loading
Loading
Loading
Loading
Loading
+13 −3
Changes for core/lib/Drupal/Component/Utility/UrlHelper.php: 13 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -16,6 +16,14 @@ class UrlHelper {
   */
  protected static $allowedProtocols = ['http', 'https'];

  /**
   * The length limit for gzuncompress().
   *
   * Because query strings come from the request, set a 10000 limit to avoid
   * implausibly large compressed strings being sent.
   */
  protected const int GZUNCOMPRESS_LIMIT = 10000;

  /**
   * Parses an array into a valid query string encoded with rawurlencode().
   *
@@ -101,9 +109,11 @@ public static function compressQueryParameter(string $data): string {
   * @see \Drupal\Component\Utility\UrlHelper::compressQueryParameter()
   */
  public static function uncompressQueryParameter(string $compressed): string {
    // Because this comes from user data, suppress the PHP warning that
    // gzcompress() throws if the base64-encoded string is invalid.
    $return = @gzuncompress(base64_decode(str_replace(['-', '_'], ['+', '/'], $compressed)));
    // Because this comes from the request, suppress the PHP warning that
    // gzuncompress() throws if the base64-encoded string is invalid.
    // Additionally, set a limit to avoid implausibly large compressed strings
    // being sent.
    $return = @gzuncompress(base64_decode(str_replace(['-', '_'], ['+', '/'], $compressed)), static::GZUNCOMPRESS_LIMIT);

    // If we failed to uncompress the query parameter, it may be a stale link
    // from before compression was implemented with the URL parameter
+10 −0
Changes for core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -152,6 +152,16 @@ public function testCompressUncompress(): void {
    $this->assertLessThan(strlen($uncompressed), strlen($compressed));
  }

  /**
   * Tests decompressing a query parameter with data over the length limit.
   */
  public function testUncompressExceededLengthLimit(): void {
    $data = str_repeat('a', 20000);
    $compressed = UrlHelper::compressQueryParameter($data);

    $this->assertSame($compressed, UrlHelper::uncompressQueryParameter($compressed));
  }

  /**
   * Tests passing an invalid string as a compressed query parameter.
   */