WebCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2007 00:24:48 +0000 (00:24 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2007 00:24:48 +0000 (00:24 +0000)
        Reviewed by Darin.

        More of http://bugs.webkit.org/show_bug.cgi?id=16385
        Cleanup kjs_window

        - Move PausedTimeouts into its own file and put it in the WebCore namespace.

        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * WebCoreSources.bkl:
        * bindings/js/PausedTimeouts.cpp: Copied from bindings/js/kjs_window.cpp.
        * bindings/js/PausedTimeouts.h: Copied from bindings/js/kjs_window.h.
        * bindings/js/kjs_window.cpp:
        (KJS::Window::pauseTimeouts):
        * bindings/js/kjs_window.h:
        * history/CachedPage.cpp:
        * history/CachedPage.h:
        * page/Chrome.cpp:

LayoutTests:

        Reviewed by Maciej.

        - tests for the argument handling of the executeSql function

        * storage/execute-sql-args-expected.txt: Added.
        * storage/execute-sql-args.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/storage/execute-sql-args-expected.txt [new file with mode: 0644]
LayoutTests/storage/execute-sql-args.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/bindings/js/JSSQLTransactionCustom.cpp

index b26133a407863bb342f210d6df036c9a10e8baca..a6976507a4c11f711ce016cae3c848f646704b3c 100644 (file)
@@ -1,3 +1,12 @@
+2007-12-16  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - tests for the argument handling of the executeSql function
+
+        * storage/execute-sql-args-expected.txt: Added.
+        * storage/execute-sql-args.html: Added.
+
 2007-12-16  Darin Adler  <darin@apple.com>
 
         - try to get the system color test passing on the buildbot
diff --git a/LayoutTests/storage/execute-sql-args-expected.txt b/LayoutTests/storage/execute-sql-args-expected.txt
new file mode 100644 (file)
index 0000000..a757317
--- /dev/null
@@ -0,0 +1,29 @@
+PASS. executeSql() did not throw an exception
+PASS. executeSql(null) did not throw an exception
+PASS. executeSql(undefined) did not throw an exception
+PASS. executeSql(0) did not throw an exception
+PASS. executeSql("") did not throw an exception
+PASS. executeSql("", null) did not throw an exception
+PASS. executeSql("", undefined) did not throw an exception
+PASS. executeSql("", []) did not throw an exception
+PASS. executeSql("", [ "arg0" ]) did not throw an exception
+PASS. executeSql("", { }) did not throw an exception
+PASS. executeSql("", { length: 0 }) did not throw an exception
+PASS. executeSql("", { length: 1, 0: "arg0" }) did not throw an exception
+PASS. executeSql("", null, null) did not throw an exception
+PASS. executeSql("", null, undefined) did not throw an exception
+PASS. executeSql("", null, { }) did not throw an exception
+PASS. executeSql("", null, null, null) did not throw an exception
+PASS. executeSql("", null, null, undefined) did not throw an exception
+PASS. executeSql("", null, null, { }) did not throw an exception
+PASS. executeSql(throwOnToStringObject) threw an exception as expected: Cannot call toString on this object.
+PASS. executeSql("", throwOnGetLengthObject) threw an exception as expected: Cannot get length of this object.
+PASS. executeSql("", throwOnGetZeroObject) threw an exception as expected: Cannot get 0 property of this object.
+PASS. executeSql("", [ throwOnToStringObject ]) threw an exception as expected: Cannot call toString on this object.
+PASS. executeSql("", 0) threw an exception as expected: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+PASS. executeSql("", "") threw an exception as expected: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+PASS. executeSql("", null, 0) threw an exception as expected: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+PASS. executeSql("", null, "") threw an exception as expected: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+PASS. executeSql("", null, null, 0) threw an exception as expected: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+PASS. executeSql("", null, null, "") threw an exception as expected: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+
diff --git a/LayoutTests/storage/execute-sql-args.html b/LayoutTests/storage/execute-sql-args.html
new file mode 100644 (file)
index 0000000..f948278
--- /dev/null
@@ -0,0 +1,108 @@
+<html>
+
+<head>
+<script>
+
+var throwOnToStringObject = { };
+throwOnToStringObject.toString = function () { throw "Cannot call toString on this object." };
+
+var throwOnGetLengthObject = { };
+throwOnGetLengthObject.__defineGetter__("length", function () { throw "Cannot get length of this object."; });
+
+var throwOnGetZeroObject = { length: 1 };
+throwOnGetZeroObject.__defineGetter__("0", function () { throw "Cannot get 0 property of this object."; });
+
+var expectNoException = [
+    '',
+    'null',
+    'undefined',
+    '0',
+    '""',
+    '"", null',
+    '"", undefined',
+    '"", []',
+    '"", [ "arg0" ]',
+    '"", { }',
+    '"", { length: 0 }',
+    '"", { length: 1, 0: "arg0" }',
+    '"", null, null',
+    '"", null, undefined',
+    '"", null, { }',
+    '"", null, null, null',
+    '"", null, null, undefined',
+    '"", null, null, { }',
+];
+
+var expectException = [
+    'throwOnToStringObject',
+    '"", throwOnGetLengthObject',
+    '"", throwOnGetZeroObject',
+    '"", [ throwOnToStringObject ]',
+    '"", 0',
+    '"", ""',
+    '"", null, 0',
+    '"", null, ""',
+    '"", null, null, 0',
+    '"", null, null, ""',
+];
+
+function writeMessageToLog(message)
+{
+    document.getElementById("console").innerText += message + "\n";
+}
+
+function tryExecuteSql(transaction, parameterList)
+{
+    try {
+        eval('transaction.executeSql(' + parameterList + ')');
+        return null;
+    } catch (exception) {
+        return exception;
+    }
+}
+
+function runTransactionTest(transaction, parameterList, expectException)
+{
+    var exception = tryExecuteSql(transaction, parameterList);
+    if (expectException) {
+        if (exception)
+            writeMessageToLog("PASS. executeSql(" + parameterList + ") threw an exception as expected: " + exception);
+        else
+            writeMessageToLog("*FAIL*. executeSql(" + parameterList + ") did not throw an exception");
+    } else {
+        if (exception)
+            writeMessageToLog("*FAIL*. executeSql(" + parameterList + ") threw an exception: " + exception);
+        else
+            writeMessageToLog("PASS. executeSql(" + parameterList + ") did not throw an exception");
+    }
+}
+
+function runTransactionTests(transaction)
+{
+    for (i in expectNoException)
+        runTransactionTest(transaction, expectNoException[i], false);
+    for (i in expectException)
+        runTransactionTest(transaction, expectException[i], true);
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    var db = openDatabase("ExecuteSQLArgsTest", "1.0", "Test of handling of the arguments to SQLTransaction.executeSql", 1);
+    db.transaction(runTransactionTests);
+}
+
+</script>
+</head>
+
+<body onload="runTest()">
+<pre id="console"></pre>
+</body>
+
+</html>
index ac920f88b00a55cdfacef48b7a462bfe6adcf4e7..acf6cc875b92309bdc5e0d332cfd0f92019ba6ec 100644 (file)
         * rendering/RenderObject.cpp:
         (WebCore::RenderObject::paintBorderImage):
 
+2007-12-16  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - fix <rdar://problem/5636065> First form of SQLTransaction.executeSql() fails with TYPE_ERROR dom exception
+
+        Test: storage/execute-sql-args.html
+
+        * bindings/js/JSSQLTransactionCustom.cpp:
+        (WebCore::JSSQLTransaction::executeSql): Added exception handling code so that once an
+        exception happens, we won't try to do any more argument processing. Changed processing
+        of the second argument so that we allow an undefined value or null, and simply omit the
+        array. Changed processing of the second argument so that we don't require an actual
+        JavaScript array. Instead, as with the JavaScript array operations themselves, we use
+        the length property and corresponding numeric properties of the object, allowing other
+        objects to act as arrays. Changed processing of the third and fourth arguments to
+        allow the undefined value as well as null; we check the value of the argument rather
+        than looking at the size of the passed-in arguments list.
+
 2007-12-16  Darin Adler  <darin@apple.com>
 
         - fix Tiger build (my fault it was broken)
index 4573557368483b5d198aea2a3d754dfe56ddd405..1dca46dea1819e4cea96a46e54c48ce9a22f6e7e 100644 (file)
@@ -25,6 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #include "config.h"
 #include "JSSQLTransaction.h"
 
 #include "ExceptionCode.h"
 #include "JSCustomSQLStatementCallback.h"
 #include "JSCustomSQLStatementErrorCallback.h"
-#include "kjs_window.h"
-#include "PlatformString.h"
 #include "SQLTransaction.h"
-#include "SQLValue.h"
-#include <kjs/array_instance.h>
+#include "kjs_window.h"
 
 using namespace KJS;
 
@@ -45,33 +43,45 @@ namespace WebCore {
 JSValue* JSSQLTransaction::executeSql(ExecState* exec, const List& args)
 {
     String sqlStatement = args[0]->toString(exec);
-    
+    if (exec->hadException())
+        return jsUndefined();
+
     // Now assemble the list of SQL arguments
     Vector<SQLValue> sqlValues;
-    
-    if (!args[1]->isObject() ||
-        !static_cast<JSObject*>(args[1])->inherits(&ArrayInstance::info)) {
-        setDOMException(exec, TYPE_MISMATCH_ERR);
-        return jsUndefined();
-    }
-    
-    ArrayInstance* array = static_cast<ArrayInstance*>(args[1]);
-    
-    for (unsigned i = 0 ; i < array->getLength(); i++) {
-        JSValue* value = array->getItem(i);
+    if (!args[1]->isUndefinedOrNull()) {
+        JSObject* object = args[1]->getObject();
+        if (!object) {
+            setDOMException(exec, TYPE_MISMATCH_ERR);
+            return jsUndefined();
+        }
+
+        JSValue* lengthValue = object->get(exec, exec->propertyNames().length);
+        if (exec->hadException())
+            return jsUndefined();
+        unsigned length = lengthValue->toUInt32(exec);
+        if (exec->hadException())
+            return jsUndefined();
         
-        if (value->isNull()) {
-            sqlValues.append(SQLValue());
-        } else if (value->isNumber()) {
-            sqlValues.append(value->getNumber());
-        } else {
-            // Convert the argument to a string and append it
-            sqlValues.append(value->toString(exec));
+        for (unsigned i = 0 ; i < length; ++i) {
+            JSValue* value = object->get(exec, i);
+            if (exec->hadException())
+                return jsUndefined();
+            
+            if (value->isNull())
+                sqlValues.append(SQLValue());
+            else if (value->isNumber())
+                sqlValues.append(value->getNumber());
+            else {
+                // Convert the argument to a string and append it
+                sqlValues.append(value->toString(exec));
+                if (exec->hadException())
+                    return jsUndefined();
+            }
         }
     }
 
     RefPtr<SQLStatementCallback> callback;
-    if (args.size() > 2 && !args[2]->isNull()) {
+    if (!args[2]->isUndefinedOrNull()) {
         JSObject* object = args[2]->getObject();
         if (!object) {
             setDOMException(exec, TYPE_MISMATCH_ERR);
@@ -83,7 +93,7 @@ JSValue* JSSQLTransaction::executeSql(ExecState* exec, const List& args)
     }
     
     RefPtr<SQLStatementErrorCallback> errorCallback;
-    if (args.size() > 3 && !args[3]->isNull()) {
+    if (!args[3]->isUndefinedOrNull()) {
         JSObject* object = args[3]->getObject();
         if (!object) {
             setDOMException(exec, TYPE_MISMATCH_ERR);