Skip to content

Commit

Permalink
TextDecoder: fix decode() ignoring TypedArray's byteLength/byteOffset
Browse files Browse the repository at this point in the history
  • Loading branch information
duonglaiquang committed Aug 27, 2024
1 parent af041bc commit 335f99f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
41 changes: 25 additions & 16 deletions src/main/java/org/htmlunit/javascript/host/TextDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.htmlunit.javascript.host;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Locale;

import org.htmlunit.corejs.javascript.typedarrays.NativeArrayBuffer;
Expand Down Expand Up @@ -79,29 +80,37 @@ public String decode(final Object buffer) {
return "";
}

NativeArrayBuffer arrayBuffer = null;
if (buffer instanceof NativeArrayBuffer) {
arrayBuffer = (NativeArrayBuffer) buffer;
}
else if (buffer instanceof NativeArrayBufferView) {
arrayBuffer = ((NativeArrayBufferView) buffer).getBuffer();
return new String(((NativeArrayBuffer) buffer).getBuffer(), getEncoding(whatwgEncoding_));
}

if (arrayBuffer != null) {
if (XUserDefinedCharset.NAME.equalsIgnoreCase(whatwgEncoding_)) {
return new String(arrayBuffer.getBuffer(), XUserDefinedCharset.INSTANCE);
if (buffer instanceof NativeArrayBufferView) {
final NativeArrayBufferView arrayBufferView = (NativeArrayBufferView) buffer;
final NativeArrayBuffer arrayBuffer = arrayBufferView.getBuffer();
if (arrayBuffer != null) {
final int byteLength = arrayBufferView.getByteLength();
final int byteOffset = arrayBufferView.getByteOffset();
final byte[] backedBytes = arrayBuffer.getBuffer();
final byte[] bytes = Arrays.copyOfRange(backedBytes, byteOffset, byteOffset + byteLength);
return new String(bytes, getEncoding(whatwgEncoding_));
}

final String ianaEncoding = StandardEncodingTranslator
.ENCODING_TO_IANA_ENCODING.getOrDefault(whatwgEncoding_, whatwgEncoding_);
// Convert our IANA encoding names to Java charset names
final String javaEncoding = StandardEncodingTranslator
.IANA_TO_JAVA_ENCODINGS.getOrDefault(ianaEncoding, ianaEncoding);

return new String(arrayBuffer.getBuffer(), Charset.forName(javaEncoding));
}

throw JavaScriptEngine.typeError("Argument 1 of TextDecoder.decode could not be"
+ " converted to any of: ArrayBufferView, ArrayBuffer.");
}

private Charset getEncoding(final String encodingLabel) {
if (XUserDefinedCharset.NAME.equalsIgnoreCase(encodingLabel)) {
return XUserDefinedCharset.INSTANCE;
}

final String ianaEncoding = StandardEncodingTranslator
.ENCODING_TO_IANA_ENCODING.getOrDefault(encodingLabel, encodingLabel);
// Convert our IANA encoding names to Java charset names
final String javaEncoding = StandardEncodingTranslator
.IANA_TO_JAVA_ENCODINGS.getOrDefault(ianaEncoding, ianaEncoding);

return Charset.forName(javaEncoding);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ public void encode() throws Exception {
* @throws Exception on test failure
*/
@Test
@Alerts("HtmlUnit")
@Alerts({"HtmlUnit", "mlU"})
public void decode() throws Exception {
final String html = "<html>\n"
+ "<head>\n"
Expand All @@ -686,6 +686,10 @@ public void decode() throws Exception {
+ " var dec = new TextDecoder('utf-8');\n"
+ " var decoded = dec.decode(encoded);\n"
+ " log(decoded);\n"

+ " var arrayBuffer = encoded.buffer;\n"
+ " var typedArray = new Uint8Array(arrayBuffer, 2, 3);\n"
+ " log(dec.decode(typedArray));\n"
+ " }\n"
+ " </script>\n"
+ "</head>\n"
Expand Down

0 comments on commit 335f99f

Please sign in to comment.