Bug 463907 - mozStorageConnection::ExecuteAsync does not check that provided statements have not been finalized; r=sdwilsh
authorAndrew Sutherland <bugmail@asutherland.org>
Tue, 03 Feb 2009 15:42:22 +0100
changeset 24553 39219f4ec8101f1ff11c5d7175b5337a21ef4503
parent 24552 cdd059f3d2005defcc2ebf66206fe264ac5e4191
child 24554 13b5a7af35bbf3f026ef44577db05615a6133cde
push id5113
push usersgautherie.bz@free.fr
push dateTue, 03 Feb 2009 14:44:19 +0000
treeherdermozilla-central@c23d77b0d600 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssdwilsh
bugs463907
milestone1.9.2a1pre
Bug 463907 - mozStorageConnection::ExecuteAsync does not check that provided statements have not been finalized; r=sdwilsh
storage/src/mozStorageConnection.cpp
storage/test/unit/test_storage_statement_executeAsync.js
--- a/storage/src/mozStorageConnection.cpp
+++ b/storage/src/mozStorageConnection.cpp
@@ -394,16 +394,20 @@ mozStorageConnection::ExecuteAsync(mozIS
                                    PRUint32 aNumStatements,
                                    mozIStorageStatementCallback *aCallback,
                                    mozIStoragePendingStatement **_stmt)
 {
     int rc = SQLITE_OK;
     nsTArray<sqlite3_stmt *> stmts(aNumStatements);
     for (PRUint32 i = 0; i < aNumStatements && rc == SQLITE_OK; i++) {
         sqlite3_stmt *old_stmt = aStatements[i]->GetNativeStatementPointer();
+        if (!old_stmt) {
+          rc = SQLITE_MISUSE;
+          break;
+        }
         NS_ASSERTION(sqlite3_db_handle(old_stmt) == mDBConn,
                      "Statement must be from this database connection!");
 
         // Clone this statement.  We only need a sqlite3_stmt object, so we can
         // avoid all the extra work that making a new mozStorageStatement would
         // normally involve and use the SQLite API.
         sqlite3_stmt *new_stmt;
         rc = sqlite3_prepare_v2(mDBConn, sqlite3_sql(old_stmt), -1, &new_stmt,
--- a/storage/test/unit/test_storage_statement_executeAsync.js
+++ b/storage/test/unit/test_storage_statement_executeAsync.js
@@ -476,28 +476,44 @@ function test_double_execute()
   }
   do_test_pending();
   stmt.executeAsync(listener);
   do_test_pending();
   stmt.executeAsync(listener);
   stmt.finalize();
 }
 
+function test_finalized_statement_does_not_crash()
+{
+  dump("test_finalized_statement_does_not_crash()\n");
+
+  var stmt = getOpenedDatabase().createStatement(
+    "SELECT * FROM TEST"
+  );
+  stmt.finalize();
+  // we are concerned about a crash here; an error is fine.
+  try {
+    stmt.executeAsync();
+  }
+  catch (ex) {}
+}
+
 var tests =
 [
   test_add_data,
   test_get_data,
   test_tuple_out_of_bounds,
   test_no_listener_works_on_success,
   test_no_listener_works_on_results,
   test_no_listener_works_on_error,
   test_partial_listener_works,
   test_immediate_cancellation,
   test_double_cancellation,
   test_double_execute,
+  test_finalized_statement_does_not_crash,
 ];
 
 function run_test()
 {
   cleanup();
 
   // This test has to run first and run to completion.  When it is done, it will
   // run the rest of the tests.