Improve the BaseStream.prototype.clone implementations

- The `dict` field is optional, hence avoid an Error if trying to clone a non-existent dictionary.

 - Use the `length` getter in the `Stream` class, to avoid duplication.

 - Fix the `DecodeStream` implementation, since it has a couple of bugs:
    - The `clone` method currently uses `start`/`end` fields, despite these only existing on `Stream` instances.
    - Given the previous point, we ended up creating the cloned `Stream` instance using the *entire* underlying `buffer`. This is problematic since the length of a `DecodeStream` cannot be accurately estimated before decoding, and the `buffer`-length is simply a multiple of two.
       Unless the size of the decoded-data just happens to also be a multiple of two, this causes the cloned `Stream` instance to be "padded" with zeros at the end.
This commit is contained in:
Jonas Jenwald 2026-05-31 18:52:59 +02:00
parent 5fbab91f71
commit a6321e7201
3 changed files with 11 additions and 12 deletions

View File

@ -135,6 +135,10 @@ class BaseStream {
unreachable("Abstract method `makeSubStream` called");
}
clone() {
unreachable("Abstract method `clone` called");
}
/**
* @returns {Array | null}
*/

View File

@ -178,21 +178,16 @@ class DecodeStream extends BaseStream {
return new Stream(this.buffer, start, length, dict);
}
getBaseStreams() {
return this.stream ? this.stream.getBaseStreams() : null;
}
clone() {
// Make sure it has been fully read.
while (!this.eof) {
this.readBlock();
}
return new Stream(
this.buffer,
this.start,
this.end - this.start,
this.dict.clone()
);
return new Stream(this.buffer, 0, this.bufferLength, this.dict?.clone());
}
getBaseStreams() {
return this.stream ? this.stream.getBaseStreams() : null;
}
}

View File

@ -88,8 +88,8 @@ class Stream extends BaseStream {
return new Stream(
this.bytes.buffer,
this.start,
this.end - this.start,
this.dict.clone()
this.length,
this.dict?.clone()
);
}
}