gecko-dev/dom/html/test/forms/test_input_sanitization.html
Brian Grinstead 0d460e3432 Bug 1544322 - Part 2.2 - Remove the [type] attribute for one-liner <script> tags loading files in /tests/SimpleTest/ in dom/ r=bzbarsky
This is split from the previous changeset since if we include dom/ the file size is too
large for phabricator to handle.

This is an autogenerated commit to handle scripts loading mochitest harness files, in
the simple case where the script src is on the same line as the tag.

This was generated with https://bug1544322.bmoattachments.org/attachment.cgi?id=9058170
using the `--part 2` argument.

Differential Revision: https://phabricator.services.mozilla.com/D27457

--HG--
extra : moz-landing-system : lando
2019-04-16 03:53:28 +00:00

586 lines
15 KiB
HTML

<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=549475
-->
<head>
<title>Test for Bug 549475</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=549475">Mozilla Bug 549475</a>
<p id="display"></p>
<pre id="test">
<div id='content'>
<form>
</form>
</div>
<script type="application/javascript">
SimpleTest.requestLongerTimeout(2);
/**
* This files tests the 'value sanitization algorithm' for the various input
* types. Note that an input's value is affected by more than just its type's
* value sanitization algorithm; e.g. some type=range has actions that the user
* agent must perform to change the element's value to avoid underflow/overflow
* and step mismatch (when possible). We specifically avoid triggering these
* other actions here so that this test only tests the value sanitization
* algorithm for the various input types.
*
* XXXjwatt splitting out testing of the value sanitization algorithm and
* "other things" that affect .value makes it harder to know what we're testing
* and what we've missed, because what's included in the value sanitization
* algorithm and what's not is different from input type to input type. It
* seems to me it would be better to have a test (maybe one per type) focused
* on testing .value for permutations of all other inputs that can affect it.
* The value sanitization algorithm is just an internal spec concept after all.
*/
// We buffer up the results of sets of sub-tests, and avoid outputting log
// entries for them all if they all pass. Otherwise, we have an enormous amount
// of test output.
var delayedTests = [];
var anyFailedDelayedTests = false;
function delayed_is(actual, expected, description)
{
var result = actual == expected;
delayedTests.push({ actual: actual, expected: expected, description: description });
if (!result) {
anyFailedDelayedTests = true;
}
}
function flushDelayedTests(description)
{
if (anyFailedDelayedTests) {
info("Outputting individual results for \"" + description + "\" due to failures in subtests");
for (var test of delayedTests) {
is(test.actual, test.expected, test.description);
}
} else {
ok(true, description + " (" + delayedTests.length + " subtests)");
}
delayedTests = [];
anyFailedDelayedTests = false;
}
// We are excluding "file" because it's too different from the other types.
// And it has no sanitizing algorithm.
var inputTypes =
[
"text", "password", "search", "tel", "hidden", "checkbox", "radio",
"submit", "image", "reset", "button", "email", "url", "number", "date",
"time", "range", "color", "month", "week", "datetime-local"
];
var valueModeValue =
[
"text", "search", "url", "tel", "email", "password", "date", "datetime",
"month", "week", "time", "datetime-local", "number", "range", "color",
];
function sanitizeDate(aValue)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-date-string
function getNumbersOfDaysInMonth(aMonth, aYear) {
if (aMonth === 2) {
return (aYear % 400 === 0 || (aYear % 100 != 0 && aYear % 4 === 0)) ? 29 : 28;
}
return (aMonth === 1 || aMonth === 3 || aMonth === 5 || aMonth === 7 ||
aMonth === 8 || aMonth === 10 || aMonth === 12) ? 31 : 30;
}
var match = /^([0-9]{4,})-([0-9]{2})-([0-9]{2})$/.exec(aValue);
if (!match) {
return "";
}
var year = Number(match[1]);
if (year === 0) {
return "";
}
var month = Number(match[2]);
if (month > 12 || month < 1) {
return "";
}
var day = Number(match[3]);
return 1 <= day && day <= getNumbersOfDaysInMonth(month, year) ? aValue : "";
}
function sanitizeTime(aValue)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-time-string
var match = /^([0-9]{2}):([0-9]{2})(.*)$/.exec(aValue);
if (!match) {
return "";
}
var hours = match[1];
if (hours < 0 || hours > 23) {
return "";
}
var minutes = match[2];
if (minutes < 0 || minutes > 59) {
return "";
}
var other = match[3];
if (other == "") {
return aValue;
}
match = /^:([0-9]{2})(.*)$/.exec(other);
if (!match) {
return "";
}
var seconds = match[1];
if (seconds < 0 || seconds > 59) {
return "";
}
var other = match[2];
if (other == "") {
return aValue;
}
match = /^.([0-9]{1,3})$/.exec(other);
if (!match) {
return "";
}
return aValue;
}
function sanitizeDateTimeLocal(aValue)
{
// https://html.spec.whatwg.org/multipage/infrastructure.html#valid-local-date-and-time-string
if (aValue.length < 16) {
return "";
}
var sepIndex = aValue.indexOf("T");
if (sepIndex == -1) {
sepIndex = aValue.indexOf(" ");
if (sepIndex == -1) {
return "";
}
}
var [date, time] = aValue.split(aValue[sepIndex]);
if (!sanitizeDate(date)) {
return "";
}
if (!sanitizeTime(time)) {
return "";
}
// Normalize datetime-local string.
// https://html.spec.whatwg.org/multipage/infrastructure.html#valid-normalised-local-date-and-time-string
if (aValue[sepIndex] == " ") {
aValue = date + "T" + time;
}
if ((aValue.length - sepIndex) == 6) {
return aValue;
}
if ((aValue.length - sepIndex) > 9) {
var milliseconds = aValue.substring(sepIndex + 10);
if (Number(milliseconds) != 0) {
return aValue;
}
aValue = aValue.slice(0, sepIndex + 9);
}
var seconds = aValue.substring(sepIndex + 7);
if (Number(seconds) != 0) {
return aValue;
}
aValue = aValue.slice(0, sepIndex + 6);
return aValue;
}
function sanitizeValue(aType, aValue)
{
// http://www.whatwg.org/html/#value-sanitization-algorithm
switch (aType) {
case "text":
case "password":
case "search":
case "tel":
return aValue.replace(/[\n\r]/g, "");
case "url":
case "email":
return aValue.replace(/[\n\r]/g, "").replace(/^[\u0020\u0009\t\u000a\u000c\u000d]+|[\u0020\u0009\t\u000a\u000c\u000d]+$/g, "");
case "number":
return isNaN(Number(aValue)) ? "" : aValue;
case "range":
var defaultMinimum = 0;
var defaultMaximum = 100;
var value = Number(aValue);
if (isNaN(value)) {
return ((defaultMaximum - defaultMinimum)/2).toString(); // "50"
}
if (value < defaultMinimum) {
return defaultMinimum.toString();
}
if (value > defaultMaximum) {
return defaultMaximum.toString();
}
return aValue;
case "date":
return sanitizeDate(aValue);
case "time":
return sanitizeTime(aValue);
case "month":
// https://html.spec.whatwg.org/multipage/infrastructure.html#valid-month-string
var match = /^([0-9]{4,})-([0-9]{2})$/.exec(aValue);
if (!match) {
return "";
}
var year = Number(match[1]);
if (year === 0) {
return "";
}
var month = Number(match[2]);
if (month > 12 || month < 1) {
return "";
}
return aValue;
case "week":
// https://html.spec.whatwg.org/multipage/infrastructure.html#valid-week-string
function isLeapYear(aYear) {
return ((aYear % 4 == 0) && (aYear % 100 != 0)) || (aYear % 400 == 0);
}
function getDayofWeek(aYear, aMonth, aDay) { /* 0 = Sunday */
// Tomohiko Sakamoto algorithm.
var monthTable = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4];
aYear -= Number(aMonth < 3);
return (aYear + parseInt(aYear / 4) - parseInt(aYear / 100) +
parseInt(aYear / 400) + monthTable[aMonth - 1] + aDay) % 7;
}
function getMaximumWeekInYear(aYear) {
var day = getDayofWeek(aYear, 1, 1);
return day == 4 || (day == 3 && isLeapYear(aYear)) ? 53 : 52;
}
var match = /^([0-9]{4,})-W([0-9]{2})$/.exec(aValue);
if (!match) {
return "";
}
var year = Number(match[1]);
if (year === 0) {
return "";
}
var week = Number(match[2]);
if (week > 53 || month < 1) {
return "";
}
return 1 <= week && week <= getMaximumWeekInYear(year) ? aValue : "";
case "datetime-local":
return sanitizeDateTimeLocal(aValue);
case "color":
return /^#[0-9A-Fa-f]{6}$/.exec(aValue) ? aValue.toLowerCase() : "#000000";
default:
return aValue;
}
}
function checkSanitizing(element, inputTypeDescription)
{
var testData =
[
// For text, password, search, tel, email:
"\n\rfoo\n\r",
"foo\n\rbar",
" foo ",
" foo\n\r bar ",
// For url:
"\r\n foobar \n\r",
"\u000B foo \u000B",
"\u000A foo \u000A",
"\u000C foo \u000C",
"\u000d foo \u000d",
"\u0020 foo \u0020",
" \u0009 foo \u0009 ",
// For number and range:
"42",
"13.37",
"1.234567898765432",
"12foo",
"1e2",
"3E42",
// For date:
"1970-01-01",
"1234-12-12",
"1234567890-01-02",
"2012-12-31",
"2012-02-29",
"2000-02-29",
"1234",
"1234-",
"12345",
"1234-01",
"1234-012",
"1234-01-",
"12-12",
"999-01-01",
"1234-56-78-91",
"1234-567-78",
"1234--7-78",
"abcd-12-12",
"thisinotadate",
"2012-13-01",
"1234-12-42",
" 2012-13-01",
" 123-01-01",
"2012- 3-01",
"12- 10- 01",
" 12-0-1",
"2012-3-001",
"2012-12-00",
"2012-12-1r",
"2012-11-31",
"2011-02-29",
"2100-02-29",
"a2000-01-01",
"2000a-01-0'",
"20aa00-01-01",
"2000a2000-01-01",
"2000-1-1",
"2000-1-01",
"2000-01-1",
"2000-01-01 ",
"2000- 01-01",
"-1970-01-01",
"0000-00-00",
"0001-00-00",
"0000-01-01",
"1234-12 12",
"1234 12-12",
"1234 12 12",
// For time:
"1",
"10",
"10:",
"10:1",
"21:21",
":21:21",
"-21:21",
" 21:21",
"21-21",
"21:21:",
"21:211",
"121:211",
"21:21 ",
"00:00",
"-1:00",
"24:00",
"00:60",
"01:01",
"23:59",
"99:99",
"8:30",
"19:2",
"19:a2",
"4c:19",
"10:.1",
"1.:10",
"13:37:42",
"13:37.42",
"13:37:42 ",
"13:37:42.",
"13:37:61.",
"13:37:00",
"13:37:99",
"13:37:b5",
"13:37:-1",
"13:37:.1",
"13:37:1.",
"13:37:42.001",
"13:37:42.001",
"13:37:42.abc",
"13:37:42.00c",
"13:37:42.a23",
"13:37:42.12e",
"13:37:42.1e1",
"13:37:42.e11",
"13:37:42.1",
"13:37:42.99",
"13:37:42.0",
"13:37:42.00",
"13:37:42.000",
"13:37:42.-1",
"13:37:42.1.1",
"13:37:42.1,1",
"13:37:42.",
"foo12:12",
"13:37:42.100000000000",
// For color
"#00ff00",
"#000000",
"red",
"#0f0",
"#FFFFAA",
"FFAABB",
"fFAaBb",
"FFAAZZ",
"ABCDEF",
"#7654321",
// For month
"1970-01",
"1234-12",
"123456789-01",
"2013-13",
"0000-00",
"2015-00",
"0001-01",
"1-1",
"888-05",
"2013-3",
"2013-may",
"2000-1a",
"2013-03-13",
"december",
"abcdef",
"12",
" 2013-03",
"2013 - 03",
"2013 03",
"2013/03",
// For week
"1970-W01",
"1970-W53",
"1964-W53",
"1900-W10",
"2004-W53",
"2065-W53",
"2099-W53",
"2010-W53",
"2016-W30",
"1900-W3",
"2016-w30",
"2016-30",
"16-W30",
"2016-Week30",
"2000-100",
"0000-W01",
"00-W01",
"123456-W05",
"1985-W100",
"week",
// For datetime-local
"1970-01-01T00:00",
"1970-01-01Z12:00",
"1970-01-01 00:00:00",
"1970-01-01T00:00:00.0",
"1970-01-01T00:00:00.00",
"1970-01-01T00:00:00.000",
"1970-01-01 00:00:00.20",
"1969-12-31 23:59",
"1969-12-31 23:59:00",
"1969-12-31 23:59:00.000",
"1969-12-31 23:59:00.30",
"123456-01-01T12:00",
"123456-01-01T12:00:00",
"123456-01-01T12:00:00.0",
"123456-01-01T12:00:00.00",
"123456-01-01T12:00:00.000",
"123456-01-01T12:00:30",
"123456-01-01T12:00:00.123",
"10000-12-31 20:00",
"10000-12-31 20:00:00",
"10000-12-31 20:00:00.0",
"10000-12-31 20:00:00.00",
"10000-12-31 20:00:00.000",
"10000-12-31 20:00:30",
"10000-12-31 20:00:00.123",
"2016-13-01T12:00",
"2016-12-32T12:00",
"2016-11-08 15:40:30.0",
"2016-11-08T15:40:30.00",
"2016-11-07T17:30:10",
"2016-12-1T12:45",
"2016-12-01T12:45:30.123456",
"2016-12-01T24:00",
"2016-12-01T12:88:30",
"2016-12-01T12:30:99",
"2016-12-01T12:30:100",
"2016-12-01",
"2016-12-01T",
"2016-Dec-01T00:00",
"12-05-2016T00:00",
"datetime-local"
];
for (value of testData) {
element.setAttribute('value', value);
delayed_is(element.value, sanitizeValue(type, value),
"The value has not been correctly sanitized for type=" + type);
delayed_is(element.getAttribute('value'), value,
"The content value should not have been sanitized");
if (type in valueModeValue) {
element.setAttribute('value', 'tulip');
element.value = value;
delayed_is(element.value, sanitizeValue(type, value),
"The value has not been correctly sanitized for type=" + type);
delayed_is(element.getAttribute('value'), 'tulip',
"The content value should not have been sanitized");
}
element.setAttribute('value', '');
form.reset();
element.type = 'checkbox'; // We know this type has no sanitizing algorithm.
element.setAttribute('value', value);
delayed_is(element.value, value, "The value should not have been sanitized");
element.type = type;
delayed_is(element.value, sanitizeValue(type, value),
"The value has not been correctly sanitized for type=" + type);
delayed_is(element.getAttribute('value'), value,
"The content value should not have been sanitized");
element.setAttribute('value', '');
form.reset();
element.setAttribute('value', value);
form.reset();
delayed_is(element.value, sanitizeValue(type, value),
"The value has not been correctly sanitized for type=" + type);
delayed_is(element.getAttribute('value'), value,
"The content value should not have been sanitized");
// Cleaning-up.
element.setAttribute('value', '');
form.reset();
}
flushDelayedTests(inputTypeDescription);
}
for (type of inputTypes) {
var form = document.forms[0];
var element = document.createElement("input");
element.style.display = "none";
element.type = type;
form.appendChild(element);
checkSanitizing(element, "type=" + type + ", no frame, no editor");
element.style.display = "";
checkSanitizing(element, "type=" + type + ", frame, no editor");
element.focus();
element.blur();
checkSanitizing(element, "type=" + type + ", frame, editor");
element.style.display = "none";
checkSanitizing(element, "type=" + type + ", no frame, editor");
form.removeChild(element);
}
</script>
</pre>
</body>
</html>