Commit 9c7319db authored by Joshua Bell's avatar Joshua Bell Committed by Commit Bot

FileAPI: Upstream test cases for Unicode normalization and replacement

The Blob/File constructors should not normalize strings (since nothing
in the web platform does) but since input strings are USVStrings any
unpaired surrogates should be replaced with U+FFFD.

Bug: 509793
Change-Id: I8a01073fd52b871b64220a79ac8ea71c12e736a9
Reviewed-on: https://chromium-review.googlesource.com/812465
Commit-Queue: Joshua Bell <jsbell@chromium.org>
Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522497}
parent 3e791ee1
<!DOCTYPE html>
<meta charset="utf-8">
<title>Blob/Unicode interaction: normalization and encoding</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
'use strict';
const OMICRON_WITH_OXIA = '\u1F79'; // NFC normalized to U+3CC
const CONTAINS_UNPAIRED_SURROGATES = 'abc\uDC00def\uD800ghi';
const REPLACED = 'abc\uFFFDdef\uFFFDghi';
function readBlobAsPromise(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsText(blob);
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(reader.error);
});
}
promise_test(async t => {
const blob = new Blob([OMICRON_WITH_OXIA]);
const result = await readBlobAsPromise(blob);
assert_equals(result, OMICRON_WITH_OXIA, 'String should not be normalized');
}, 'Test that strings are not NFC normalized by Blob constructor');
promise_test(async t => {
const file = new File([OMICRON_WITH_OXIA], 'name');
const result = await readBlobAsPromise(file);
assert_equals(result, OMICRON_WITH_OXIA, 'String should not be normalized');
}, 'Test that strings are not NFC normalized by File constructor');
promise_test(async t => {
const blob = new Blob([CONTAINS_UNPAIRED_SURROGATES]);
const result = await readBlobAsPromise(blob);
assert_equals(result, REPLACED, 'Unpaired surrogates should be replaced.');
}, 'Test that unpaired surrogates are replaced by Blob constructor');
promise_test(async t => {
const file = new File([CONTAINS_UNPAIRED_SURROGATES], 'name');
const result = await readBlobAsPromise(file);
assert_equals(result, REPLACED, 'Unpaired surrogates should be replaced.');
}, 'Test that unpaired surrogates are replaced by File constructor');
</script>
...@@ -31,12 +31,6 @@ PASS new Blob([(new Float64Array(100)).buffer]).size is 800 ...@@ -31,12 +31,6 @@ PASS new Blob([(new Float64Array(100)).buffer]).size is 800
PASS new Blob([(new Float64Array(100)).buffer, (new Int32Array(100)).buffer, (new Uint8Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1400 PASS new Blob([(new Float64Array(100)).buffer, (new Int32Array(100)).buffer, (new Uint8Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1400
PASS new Blob([new Blob([(new Int32Array(100)).buffer]), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1000 PASS new Blob([new Blob([(new Int32Array(100)).buffer]), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1000
PASS new Blob([new Uint8Array(new SharedArrayBuffer(4))]) threw exception TypeError: Failed to construct 'Blob': The provided ArrayBufferView value must not be shared.. PASS new Blob([new Uint8Array(new SharedArrayBuffer(4))]) threw exception TypeError: Failed to construct 'Blob': The provided ArrayBufferView value must not be shared..
PASS OMICRON_WITH_OXIA.charCodeAt(0) is 0x1F79
PASS reader.result.charCodeAt(0) is 0x1F79
PASS CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3) is 0xDC00
PASS CONTAINS_UNPAIRED_SURROGATES.charCodeAt(7) is 0xD800
PASS reader.result.charCodeAt(3) is 0xFFFD
PASS reader.result.charCodeAt(7) is 0xFFFD
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
<script src="../../resources/js-test.js"></script> <script src="../../resources/js-test.js"></script>
<script> <script>
description("Test the Blob constructor."); description("Test the Blob constructor.");
var jsTestIsAsync = true;
// Test that the File-specific lastModified is not set by the Blob constructor. // Test that the File-specific lastModified is not set by the Blob constructor.
shouldBe("(new Blob([])).lastModified", "undefined"); shouldBe("(new Blob([])).lastModified", "undefined");
shouldBe("(new Blob([], {})).lastModified", "undefined"); shouldBe("(new Blob([], {})).lastModified", "undefined");
...@@ -42,33 +40,4 @@ if (window.SharedArrayBuffer) { ...@@ -42,33 +40,4 @@ if (window.SharedArrayBuffer) {
// Test SharedArrayBuffer parameters. // Test SharedArrayBuffer parameters.
shouldThrow("new Blob([new Uint8Array(new SharedArrayBuffer(4))])", '"TypeError: Failed to construct \'Blob\': The provided ArrayBufferView value must not be shared."'); shouldThrow("new Blob([new Uint8Array(new SharedArrayBuffer(4))])", '"TypeError: Failed to construct \'Blob\': The provided ArrayBufferView value must not be shared."');
} }
testNormalization();
function testNormalization() {
// Test that strings are not NFC normalized
OMICRON_WITH_OXIA = '\u1F79'; // NFC normalized to U+3CC
shouldBe("OMICRON_WITH_OXIA.charCodeAt(0)", "0x1F79");
reader = new FileReader();
reader.readAsText(new Blob([OMICRON_WITH_OXIA]));
reader.onload = function() {
shouldBe("reader.result.charCodeAt(0)", "0x1F79");
testEncodingReplacements();
};
}
function testEncodingReplacements() {
// Test that invalid UTF-16 code units are replaced.
CONTAINS_UNPAIRED_SURROGATES = 'abc\uDC00def\uD800ghi';
shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3)", "0xDC00");
shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(7)", "0xD800");
reader = new FileReader();
reader.readAsText(new Blob([CONTAINS_UNPAIRED_SURROGATES]));
reader.onload = function() {
shouldBe("reader.result.charCodeAt(3)", "0xFFFD");
shouldBe("reader.result.charCodeAt(7)", "0xFFFD");
finishJSTest();
};
}
</script> </script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment