Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stream: WPT fixes for Compression Streams #50712

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 41 additions & 9 deletions lib/internal/webstreams/adapters.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
'use strict';

const {
ArrayPrototypeFilter,
ArrayPrototypeMap,
Boolean,
ObjectEntries,
PromisePrototypeThen,
PromiseResolve,
SafePromiseAll,
SafePromisePrototypeFinally,
SafeSet,
TypedArrayPrototypeGetBuffer,
TypedArrayPrototypeGetByteOffset,
TypedArrayPrototypeGetByteLength,
TypedArrayPrototypeGetByteOffset,
TypeError,
Uint8Array,
} = primordials;

Expand Down Expand Up @@ -82,6 +88,38 @@ const { UV_EOF } = internalBinding('uv');

const encoder = new TextEncoder();

// Collect all negative (error) ZLIB codes and Z_NEED_DICT
const ZLIB_FAILURES = new SafeSet([
...ArrayPrototypeFilter(
ArrayPrototypeMap(
ObjectEntries(internalBinding('constants').zlib),
({ 0: code, 1: value }) => (value < 0 ? code : null),
),
Boolean,
),
'Z_NEED_DICT',
]);

/**
* @param {Error|null} cause
* @returns {Error|null}
*/
function handleKnownInternalErrors(cause) {
panva marked this conversation as resolved.
Show resolved Hide resolved
switch (true) {
case cause?.code === 'ERR_STREAM_PREMATURE_CLOSE': {
return new AbortError(undefined, { cause });
}
case ZLIB_FAILURES.has(cause?.code): {
// eslint-disable-next-line no-restricted-syntax
const error = new TypeError(undefined, { cause });
error.code = cause.code;
return error;
}
default:
return cause;
}
}

/**
* @typedef {import('../../stream').Writable} Writable
* @typedef {import('../../stream').Readable} Readable
Expand Down Expand Up @@ -137,10 +175,7 @@ function newWritableStreamFromStreamWritable(streamWritable) {
}

const cleanup = finished(streamWritable, (error) => {
if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
const err = new AbortError(undefined, { cause: error });
error = err;
}
error = handleKnownInternalErrors(error);

cleanup();
// This is a protection against non-standard, legacy streams
Expand Down Expand Up @@ -440,10 +475,7 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj
streamReadable.pause();

const cleanup = finished(streamReadable, (error) => {
if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
const err = new AbortError(undefined, { cause: error });
error = err;
}
error = handleKnownInternalErrors(error);
panva marked this conversation as resolved.
Show resolved Hide resolved

cleanup();
// This is a protection against non-standard, legacy streams
Expand Down
11 changes: 11 additions & 0 deletions lib/internal/webstreams/compression.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const {
ObjectDefineProperties,
SymbolToStringTag,
} = primordials;

const {
Expand Down Expand Up @@ -137,11 +138,21 @@ class DecompressionStream {
ObjectDefineProperties(CompressionStream.prototype, {
readable: kEnumerableProperty,
writable: kEnumerableProperty,
[SymbolToStringTag]: {
__proto__: null,
configurable: true,
value: 'CompressionStream',
},
});

ObjectDefineProperties(DecompressionStream.prototype, {
readable: kEnumerableProperty,
writable: kEnumerableProperty,
[SymbolToStringTag]: {
__proto__: null,
configurable: true,
value: 'DecompressionStream',
},
});

module.exports = {
Expand Down
4 changes: 2 additions & 2 deletions test/fixtures/wpt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ Last update:
- html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/2c5c3c4c27/html/webappapis/microtask-queuing
- html/webappapis/structured-clone: https://github.com/web-platform-tests/wpt/tree/47d3fb280c/html/webappapis/structured-clone
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/5873f2d8f1/html/webappapis/timers
- interfaces: https://github.com/web-platform-tests/wpt/tree/df731dab88/interfaces
- interfaces: https://github.com/web-platform-tests/wpt/tree/727995f043/interfaces
- performance-timeline: https://github.com/web-platform-tests/wpt/tree/17ebc3aea0/performance-timeline
- resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing
- resources: https://github.com/web-platform-tests/wpt/tree/919874f84f/resources
- resources: https://github.com/web-platform-tests/wpt/tree/1e140d63ec/resources
- streams: https://github.com/web-platform-tests/wpt/tree/517e945bbf/streams
- url: https://github.com/web-platform-tests/wpt/tree/c2d7e70b52/url
- user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing
Expand Down
22 changes: 22 additions & 0 deletions test/fixtures/wpt/interfaces/compression.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// GENERATED CONTENT - DO NOT EDIT
// Content was automatically extracted by Reffy into webref
// (https://github.com/w3c/webref)
// Source: Compression Streams (https://wicg.github.io/compression/)

enum CompressionFormat {
"deflate",
"deflate-raw",
"gzip",
};

[Exposed=*]
interface CompressionStream {
constructor(CompressionFormat format);
};
CompressionStream includes GenericTransformStream;

[Exposed=*]
interface DecompressionStream {
constructor(CompressionFormat format);
};
DecompressionStream includes GenericTransformStream;
3 changes: 2 additions & 1 deletion test/fixtures/wpt/interfaces/dom.idl
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ interface AbortController {
interface AbortSignal : EventTarget {
[NewObject] static AbortSignal abort(optional any reason);
[Exposed=(Window,Worker), NewObject] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds);
[NewObject] static AbortSignal _any(sequence<AbortSignal> signals);

readonly attribute boolean aborted;
readonly attribute any reason;
Expand Down Expand Up @@ -618,7 +619,7 @@ callback interface XPathNSResolver {

interface mixin XPathEvaluatorBase {
[NewObject] XPathExpression createExpression(DOMString expression, optional XPathNSResolver? resolver = null);
XPathNSResolver createNSResolver(Node nodeResolver);
Node createNSResolver(Node nodeResolver); // legacy
// XPathResult.ANY_TYPE = 0
XPathResult evaluate(DOMString expression, Node contextNode, optional XPathNSResolver? resolver = null, optional unsigned short type = 0, optional XPathResult? result = null);
};
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/wpt/interfaces/encoding.idl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dictionary TextDecodeOptions {
interface TextDecoder {
constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options = {});

USVString decode(optional [AllowShared] BufferSource input, optional TextDecodeOptions options = {});
USVString decode(optional AllowSharedBufferSource input, optional TextDecodeOptions options = {});
};
TextDecoder includes TextDecoderCommon;

Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/wpt/interfaces/hr-time.idl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ typedef double DOMHighResTimeStamp;

typedef unsigned long long EpochTimeStamp;

[Exposed=*]
[Exposed=(Window,Worker)]
interface Performance : EventTarget {
DOMHighResTimeStamp now();
readonly attribute DOMHighResTimeStamp timeOrigin;
Expand Down
Loading