diff --git a/src/main/java/org/htmlunit/javascript/host/TextDecoder.java b/src/main/java/org/htmlunit/javascript/host/TextDecoder.java index 632b380286..bce56f4f00 100644 --- a/src/main/java/org/htmlunit/javascript/host/TextDecoder.java +++ b/src/main/java/org/htmlunit/javascript/host/TextDecoder.java @@ -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; @@ -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); + } } diff --git a/src/test/java/org/htmlunit/javascript/host/TextDecoderTest.java b/src/test/java/org/htmlunit/javascript/host/TextDecoderTest.java index 7f3ecd8572..e0d6e63525 100644 --- a/src/test/java/org/htmlunit/javascript/host/TextDecoderTest.java +++ b/src/test/java/org/htmlunit/javascript/host/TextDecoderTest.java @@ -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 = "\n" + "\n" @@ -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" + " \n" + "\n"