REGRESSION(r164329): Input fields are not honoring the maxlength attribute
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Dec 2014 22:10:23 +0000 (22:10 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Dec 2014 22:10:23 +0000 (22:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=139447

Reviewed by Benjamin Poulain.

Source/WebCore:

The bug was caused by String::substring being called with the selection's end offset
in the second argument instead of the selection's length in handleBeforeTextInsertedEvent.

Fixed the bug by passing the right second argument to String::substring.

Test: fast/forms/input-maxlength-inserting-in-middle.html

* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::handleBeforeTextInsertedEvent):

LayoutTests:

Added regression tests.

* fast/forms/input-maxlength-inserting-in-middle-expected.txt: Added.
* fast/forms/input-maxlength-inserting-in-middle.html: Added.
* fast/forms/input-maxlength-paste-clusters-in-middle-expected.txt: Added.
* fast/forms/input-maxlength-paste-clusters-in-middle.html: Added.
* fast/forms/input-maxlength-paste-in-middle-expected.txt: Added.
* fast/forms/input-maxlength-paste-in-middle.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177098 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/forms/input-maxlength-inserting-in-middle-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/input-maxlength-inserting-in-middle.html [new file with mode: 0644]
LayoutTests/fast/forms/input-maxlength-paste-clusters-in-middle-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/input-maxlength-paste-clusters-in-middle.html [new file with mode: 0644]
LayoutTests/fast/forms/input-maxlength-paste-in-middle-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/input-maxlength-paste-in-middle.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/TextFieldInputType.cpp

index f65b646ba19bba5dc96c6a8ee0dc45e400f0a138..ff766d077a42cfd0728c27d3999014da73f70fa5 100644 (file)
@@ -1,3 +1,19 @@
+2014-12-10  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r164329): Input fields are not honoring the maxlength attribute
+        https://bugs.webkit.org/show_bug.cgi?id=139447
+
+        Reviewed by Benjamin Poulain.
+
+        Added regression tests.
+
+        * fast/forms/input-maxlength-inserting-in-middle-expected.txt: Added.
+        * fast/forms/input-maxlength-inserting-in-middle.html: Added.
+        * fast/forms/input-maxlength-paste-clusters-in-middle-expected.txt: Added.
+        * fast/forms/input-maxlength-paste-clusters-in-middle.html: Added.
+        * fast/forms/input-maxlength-paste-in-middle-expected.txt: Added.
+        * fast/forms/input-maxlength-paste-in-middle.html: Added.
+
 2014-12-10  Antti Koivisto  <antti@apple.com>
 
         Crash when creating CSSCalcBinaryOperation
diff --git a/LayoutTests/fast/forms/input-maxlength-inserting-in-middle-expected.txt b/LayoutTests/fast/forms/input-maxlength-inserting-in-middle-expected.txt
new file mode 100644 (file)
index 0000000..9ef07dc
--- /dev/null
@@ -0,0 +1,12 @@
+This test attempts to insert a character in the middle of a text field with maxlength.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.value is "abc"
+PASS input.getAttribute("maxlength") is "3"
+PASS input.value is "abc"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/input-maxlength-inserting-in-middle.html b/LayoutTests/fast/forms/input-maxlength-inserting-in-middle.html
new file mode 100644 (file)
index 0000000..26e24dd
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test-pre.js"></script>
+<input type="text" maxlength="3" value="abc">
+<script>
+
+description('This test attempts to insert a character in the middle of a text field with maxlength.');
+
+var input = document.querySelector('input');
+input.focus();
+input.selectionStart = 1;
+input.selectionEnd = 1;
+shouldBeEqualToString('input.value', 'abc');
+shouldBeEqualToString('input.getAttribute("maxlength")', '3');
+
+input.oninput = function () {
+    shouldBeEqualToString('input.value', 'abc');
+}
+
+if (window.eventSender)
+    eventSender.keyDown('1');
+else
+    debug('To test manually, type in "1" into the text field. It should fail.');
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/input-maxlength-paste-clusters-in-middle-expected.txt b/LayoutTests/fast/forms/input-maxlength-paste-clusters-in-middle-expected.txt
new file mode 100644 (file)
index 0000000..3925209
--- /dev/null
@@ -0,0 +1,15 @@
+This test attempts to paste text in the middle of a text field with maxlength.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.value is "abc"
+PASS input.getAttribute("maxlength") is "3"
+input.selectionStart = input.selectionEnd = 2
+getSelection().modify("extend", "backward", "character")
+PASS document.execCommand("insertText", false, "स्"); input.value is "aस्c"
+PASS input.value.length is 4
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/input-maxlength-paste-clusters-in-middle.html b/LayoutTests/fast/forms/input-maxlength-paste-clusters-in-middle.html
new file mode 100644 (file)
index 0000000..436e3a2
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test-pre.js"></script>
+<input type="text" maxlength="3" value="abc">
+<script>
+
+description('This test attempts to paste text in the middle of a text field with maxlength.');
+
+var input = document.querySelector('input');
+input.focus();
+input.selectionStart = 1;
+input.selectionEnd = 2;
+shouldBeEqualToString('input.value', 'abc');
+shouldBeEqualToString('input.getAttribute("maxlength")', '3');
+evalAndLog('input.selectionStart = input.selectionEnd = 2');
+evalAndLog('getSelection().modify("extend", "backward", "character")');
+shouldBeEqualToString('document.execCommand("insertText", false, "\u0938\u094D"); input.value', 'a\u0938\u094Dc');
+shouldBe('input.value.length', '4');
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/input-maxlength-paste-in-middle-expected.txt b/LayoutTests/fast/forms/input-maxlength-paste-in-middle-expected.txt
new file mode 100644 (file)
index 0000000..600157c
--- /dev/null
@@ -0,0 +1,14 @@
+This test attempts to paste text in the middle of a text field with maxlength.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.value is "abc"
+PASS input.getAttribute("maxlength") is "3"
+input.selectionStart = 1
+input.selectionEnd = 2
+PASS document.execCommand("insertText", false, "123"); input.value is "a1c"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/input-maxlength-paste-in-middle.html b/LayoutTests/fast/forms/input-maxlength-paste-in-middle.html
new file mode 100644 (file)
index 0000000..37bdc98
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test-pre.js"></script>
+<input type="text" maxlength="3" value="abc">
+<script>
+
+description('This test attempts to paste text in the middle of a text field with maxlength.');
+
+var input = document.querySelector('input');
+input.focus();
+shouldBeEqualToString('input.value', 'abc');
+shouldBeEqualToString('input.getAttribute("maxlength")', '3');
+evalAndLog('input.selectionStart = 1');
+evalAndLog('input.selectionEnd = 2');
+shouldBeEqualToString('document.execCommand("insertText", false, "123"); input.value', 'a1c');
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index 329d9b5af5bbbbe2c5b4b0fa39d0a2dc64048459..8d9e3e3b0c3bfe46eec97f11a8830b84f14656f9 100644 (file)
@@ -1,3 +1,20 @@
+2014-12-10  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r164329): Input fields are not honoring the maxlength attribute
+        https://bugs.webkit.org/show_bug.cgi?id=139447
+
+        Reviewed by Benjamin Poulain.
+
+        The bug was caused by String::substring being called with the selection's end offset
+        in the second argument instead of the selection's length in handleBeforeTextInsertedEvent.
+
+        Fixed the bug by passing the right second argument to String::substring.
+
+        Test: fast/forms/input-maxlength-inserting-in-middle.html
+
+        * html/TextFieldInputType.cpp:
+        (WebCore::TextFieldInputType::handleBeforeTextInsertedEvent):
+
 2014-12-10  Anders Carlsson  <andersca@apple.com>
 
         Add a missing null check.
index 1bbad62a4d390d293db26f1a8340406922ec8a3d..e7bc28b87bab94fd0d12352af985981667c26e4a 100644 (file)
@@ -384,7 +384,10 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
     unsigned selectionLength = 0;
     if (element().focused()) {
         ASSERT(enclosingTextFormControl(element().document().frame()->selection().selection().start()) == &element());
-        selectionLength = numGraphemeClusters(innerText.substring(element().selectionStart(), element().selectionEnd()));
+        int selectionStart = element().selectionStart();
+        ASSERT(selectionStart <= element().selectionEnd());
+        int selectionCodeUnitCount = element().selectionEnd() - selectionStart;
+        selectionLength = selectionCodeUnitCount ? numGraphemeClusters(innerText.substring(selectionStart, selectionCodeUnitCount)) : 0;
     }
     ASSERT(oldLength >= selectionLength);