<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>299541</bug_id>
          
          <creation_ts>2025-09-25 12:23:35 -0700</creation_ts>
          <short_desc>Unexpected DecompressionStream behaviour (arbitrary-padded data)</short_desc>
          <delta_ts>2026-02-16 11:48:50 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebCore Misc.</component>
          <version>Safari 18</version>
          <rep_platform>Mac (Apple Silicon)</rep_platform>
          <op_sys>macOS 15</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter>kdarutkin</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>brandonstewart</cc>
    
    <cc>cdumez</cc>
    
    <cc>webkit-bug-importer</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>2145921</commentid>
    <comment_count>0</comment_count>
      <attachid>476857</attachid>
    <who name="">kdarutkin</who>
    <bug_when>2025-09-25 12:23:35 -0700</bug_when>
    <thetext>Created attachment 476857
reproduction script (console-friendly)

Hi,

When working with DecompressionStream API I noticed a major difference between Safari, Chrome and Firefox. 

If you pass compressed binary data with arbitrary padding, the compression stream fails, however:
* In Chrome you can actually read chunks of decompressed data before encountering an error: `TypeError: Junk found after end of compressed data.`
* In Safari and Firefox behaviour depends on chunking and, in case the last chunk has some extra bytes, output is discarded and an error is triggered: `TypeError: Extra bytes past the end.` (Safari) and `TypeError: Unexpected input after the end of stream` (Firefox)

--------

After checking the spec https://compression.spec.whatwg.org/#dom-decompressionstream-decompressionstream
both behaviours are spec-compliant, since:
* The spec requires that trailing data after the end of a compressed stream is an error for all three formats.
* During per-chunk processing: decompress and enqueue a chunk says &quot;Let buffer be the result of decompressing… If this results in an error, then throw a TypeError.&quot; That means an implementation that notices the trailing bytes while handling a single incoming chunk can throw immediately, before enqueuing anything.
* At the end (on close): decompress flush and enqueue says &quot;If the end of the compressed input has not been reached, then throw a TypeError.&quot; If earlier chunks already produced output and only the final validation fails, an implementation may have already enqueued some decompressed bytes before the final error is thrown.

The spec does not mandate detecting the trailing-data error as early as possible versus only on flush, nor does it require suppressing already-enqueued output if a later error occurs. It only mandates that trailing data is an error. So Chrome’s &quot;emit some output, then throw on close&quot; and Safari/Firefox’s &quot;throw without emitting&quot; are both consistent with the current algorithms.

--------

An actual problem comes when you start passing chunked input data to the decompression stream. Let&apos;s say you feed the stream with two chunks: first one is valid and the second one is partially valid and has arbitrary padding. In this case:
* The same JS code will produce different results in Chrome and Safari/Firefox
* JS-based alternatives such as `pako` or `fflate` handles such cases without any problems 
* There&apos;s no way to tell if compressed stream is valid or padded before passing the whole payload through the `DecompressionStream` and so far the only reliable option is to try `DecompressionStream` and gracefully fallback to JS-based libraries
* Actual wording in the `TypeError` is vendor-specific and not defined by spec (therefore might change in the future), so checking if the compressed data is invalid/corrupted or just padded with arbitrary data is tricky 

The reason I&apos;m filing the ticket is because I believe Chrome&apos;s approach is more robust and intuitive and I would love to see the same behaviour in Safari

P.S. attached a reproduction script</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2145969</commentid>
    <comment_count>1</comment_count>
    <who name="">kdarutkin</who>
    <bug_when>2025-09-25 14:48:08 -0700</bug_when>
    <thetext>whatwg ticket: https://github.com/whatwg/compression/issues/76</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2146304</commentid>
    <comment_count>2</comment_count>
    <who name="Sam Sneddon [:gsnedders]">gsnedders</who>
    <bug_when>2025-09-26 14:41:56 -0700</bug_when>
    <thetext>*** Bug 299542 has been marked as a duplicate of this bug. ***</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2147635</commentid>
    <comment_count>3</comment_count>
    <who name="">kdarutkin</who>
    <bug_when>2025-10-01 13:21:35 -0700</bug_when>
    <thetext>JFYI whatwg spec was updated to cover this issue 
https://github.com/whatwg/compression/pull/77
and WPT tests are pending
https://github.com/web-platform-tests/wpt/pull/55118</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2147902</commentid>
    <comment_count>4</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2025-10-02 12:25:30 -0700</bug_when>
    <thetext>&lt;rdar://problem/161837807&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2182144</commentid>
    <comment_count>5</comment_count>
    <who name="Brandon">brandonstewart</who>
    <bug_when>2026-02-16 11:48:50 -0800</bug_when>
    <thetext>I completed the spec update here: https://github.com/WebKit/WebKit/pull/58763</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>476857</attachid>
            <date>2025-09-25 12:23:35 -0700</date>
            <delta_ts>2025-09-25 12:23:35 -0700</delta_ts>
            <desc>reproduction script (console-friendly)</desc>
            <filename>sample-streams.js</filename>
            <type>text/javascript</type>
            <size>2041</size>
            <attacher>kdarutkin</attacher>
            
              <data encoding="base64">Ly8gQ29uc29sZS1mcmllbmRseSB2ZXJzaW9uIG9mIHRoZSBzY3JpcHQKLy8gSnVzdCBwYXN0ZSBp
dCBpbnRvIHRoZSBkZXYtdG9vbHMgY29uc29sZSBpbiBDaHJvbWUvU2FmYXJpL0ZpcmVmb3gKKGFz
eW5jIGZ1bmN0aW9uIHRlc3QoKSB7CiAgY29uc3QgcGxhaW5UZXh0ID0gInRlc3QtcGF5bG9hZCI7
CiAgY29uc3QgcGxhaW5UZXh0Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUocGxhaW5U
ZXh0KTsKCiAgLy8gQ29tcHJlc3MKICBjb25zdCBjb21wcmVzc2lvblN0cmVhbSA9IG5ldyBDb21w
cmVzc2lvblN0cmVhbSgiZGVmbGF0ZSIpOwogIGNvbnN0IGNvbXByZXNzaW9uV3JpdGVyID0gY29t
cHJlc3Npb25TdHJlYW0ud3JpdGFibGUuZ2V0V3JpdGVyKCk7CiAgY29tcHJlc3Npb25Xcml0ZXIu
d3JpdGUocGxhaW5UZXh0Qnl0ZXMpOwogIGNvbXByZXNzaW9uV3JpdGVyLmNsb3NlKCk7CgogIGNv
bnN0IG9yaWdpbmFsQ29tcHJlc3NlZEJ5dGVzID0gYXdhaXQgcmVhZFN0cmVhbShjb21wcmVzc2lv
blN0cmVhbS5yZWFkYWJsZSk7CgogIC8vIEFkZCBhcmJpdHJhcnkgcGFkZGluZyB0byB0aGUgY29t
cHJlc3NlZCBieXRlcwogIGNvbnN0IHBhZGRlZENvbXByZXNzZWRCeXRlcyA9IHBhZEJ1ZmZlcihv
cmlnaW5hbENvbXByZXNzZWRCeXRlcywgMSk7CgogIC8vIERlY29tcHJlc3MKICBjb25zdCBkZWNv
bXByZXNzaW9uU3RyZWFtID0gbmV3IERlY29tcHJlc3Npb25TdHJlYW0oImRlZmxhdGUiKTsKICBj
b25zdCBkZWNvbXByZXNzaW9uV3JpdGVyID0gZGVjb21wcmVzc2lvblN0cmVhbS53cml0YWJsZS5n
ZXRXcml0ZXIoKTsKICBkZWNvbXByZXNzaW9uV3JpdGVyLndyaXRlKHBhZGRlZENvbXByZXNzZWRC
eXRlcyk7CiAgZGVjb21wcmVzc2lvbldyaXRlci5jbG9zZSgpOwoKICAvLyBJbiBDaHJvbWUgZGVj
b21wcmVzc2VkQnl0ZXMgYXJlIHN0aWxsIGF2YWlsYWJsZSBhbmQgZmluZSwgd2hlcmVhcyBpbiBT
YWZhcmkgYW5kIEZpcmVmb3ggLSBub3QgYXZhaWxhYmxlLgogIC8vIEFsc28sIHRoZSBvdXRwdXQg
ZGVwZW5kcyBvbiBpbnB1dCBjaHVua2luZyB3aGljaCBpcyBub3QgZ3VhcmFudGVlZC4KICBjb25z
dCBkZWNvbXByZXNzZWRCeXRlcyA9IGF3YWl0IHJlYWRTdHJlYW0oZGVjb21wcmVzc2lvblN0cmVh
bS5yZWFkYWJsZSk7CiAgY29uc3QgZGVjb21wcmVzc2VkVGV4dCA9IG5ldyBUZXh0RGVjb2Rlcigp
LmRlY29kZShkZWNvbXByZXNzZWRCeXRlcyk7CgogIGNvbnNvbGUubG9nKCJEZWNvbXByZXNzZWQg
dGV4dDoiLCBkZWNvbXByZXNzZWRUZXh0KTsKCiAgcmV0dXJuIGRlY29tcHJlc3NlZFRleHQ7Cn0p
KCk7Cgphc3luYyBmdW5jdGlvbiByZWFkU3RyZWFtKHJlYWRhYmxlU3RyZWFtKSB7CiAgY29uc3Qg
Y2h1bmtzID0gW107CgogIGF3YWl0IHJlYWRhYmxlU3RyZWFtCiAgICAucGlwZVRvKAogICAgICBu
ZXcgV3JpdGFibGVTdHJlYW0oewogICAgICAgIHdyaXRlKGNodW5rKSB7CiAgICAgICAgICBjaHVu
a3MucHVzaChjaHVuayk7CiAgICAgICAgfSwKICAgICAgICBhYm9ydChyZWFzb24pIHsKICAgICAg
ICAgIGNvbnNvbGUubG9nKCJhYm9ydCIsIHJlYXNvbik7CiAgICAgICAgfSwKICAgICAgfSkKICAg
ICkKICAgIC5jYXRjaCgoZXJyb3IpID0+IHsKICAgICAgY29uc29sZS5sb2coImVycm9yIiwgZXJy
b3IpOwogICAgfSk7CgogIHJldHVybiBuZXcgQmxvYihjaHVua3MpCiAgICAuYXJyYXlCdWZmZXIo
KQogICAgLnRoZW4oKGJ1ZmZlcikgPT4gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSk7Cn0KCmZ1bmN0
aW9uIHBhZEJ1ZmZlcihidWZmZXIsIHBhZGRpbmdMZW5ndGgpIHsKICBjb25zdCBwYWRkZWRCdWZm
ZXIgPSBuZXcgVWludDhBcnJheShidWZmZXIubGVuZ3RoICsgcGFkZGluZ0xlbmd0aCk7CiAgcGFk
ZGVkQnVmZmVyLnNldChidWZmZXIsIDApOwoKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhZGRpbmdM
ZW5ndGg7IGkrKykgewogICAgcGFkZGVkQnVmZmVyW2J1ZmZlci5sZW5ndGggKyBpXSA9IE1hdGgu
cmFuZG9tKCkgKiAweGZmOwogIH0KICByZXR1cm4gcGFkZGVkQnVmZmVyOwp9Cg==
</data>

          </attachment>
      

    </bug>

</bugzilla>