diff --git a/src/api.js b/src/api.js index 126baf1c..b265a0a8 100644 --- a/src/api.js +++ b/src/api.js @@ -77,14 +77,9 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { var sqlite3_exec = cwrap( "sqlite3_exec", "number", - ["number", "string", "number", "number", "number"] + ["number", "number", "number", "number", "number"] ); var sqlite3_changes = cwrap("sqlite3_changes", "number", ["number"]); - var sqlite3_prepare_v2 = cwrap( - "sqlite3_prepare_v2", - "number", - ["number", "string", "number", "number", "number"] - ); var sqlite3_sql = cwrap("sqlite3_sql", "string", ["number"]); var sqlite3_normalized_sql = cwrap( "sqlite3_normalized_sql", @@ -869,7 +864,12 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { stmt.free(); } } else { - this.handleError(sqlite3_exec(this.db, sql, 0, 0, apiTemp)); + var sqlPtr = stringToNewUTF8(sql); + try { + this.handleError(sqlite3_exec(this.db, sqlPtr, 0, 0, apiTemp)); + } finally { + _free(sqlPtr); + } } return this; }; @@ -1048,10 +1048,15 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { @throws {String} SQLite error */ Database.prototype.prepare = function prepare(sql, params) { - setValue(apiTemp, 0, "i32"); - this.handleError( - sqlite3_prepare_v2(this.db, sql, -1, apiTemp, NULL) - ); + var sqlPtr = stringToNewUTF8(sql); + try { + setValue(apiTemp, 0, "i32"); + this.handleError( + sqlite3_prepare_v2_sqlptr(this.db, sqlPtr, -1, apiTemp, NULL) + ); + } finally { + _free(sqlPtr); + } // pointer to a statement, or null var pStmt = getValue(apiTemp, "i32"); if (pStmt === NULL) { diff --git a/test/test_issue482.js b/test/test_issue482.js new file mode 100644 index 00000000..31a644f1 --- /dev/null +++ b/test/test_issue482.js @@ -0,0 +1,45 @@ +// test for https://github.com/sql-js/sql.js/issues/482 +exports.test = function (sql, assert) { + "use strict"; + // The WebAssembly stack is 5 MB, so SQL of this size cannot live on it + var text = "a".repeat(6 * 1024 * 1024); + var insert = "INSERT INTO t VALUES ('" + text + "', ?)"; + var lengths = "SELECT length(a) FROM t"; + + var db = new sql.Database(); + db.run("CREATE TABLE t (a, b)"); + + db.run("INSERT INTO t VALUES ('" + text + "', 1)"); + db.run(insert, [2]); + var stmt = db.prepare(insert, [3]); + stmt.step(); + stmt.free(); + + assert.deepEqual( + db.exec(lengths)[0].values, + [[text.length], [text.length], [text.length]], + "long SQL passed to run, run with params and prepare is executed" + ); + assert.deepEqual( + db.exec("SELECT b FROM t")[0].values, + [[1], [2], [3]], + "database is still usable after long SQL" + ); + + db.close(); +}; + +if (module == require.main) { + const target_file = process.argv[2]; + const sql_loader = require('./load_sql_lib'); + sql_loader(target_file).then((sql) => { + require('test').run({ + 'test issue482': function (assert) { + exports.test(sql, assert); + } + }); + }).catch((e) => { + console.error(e); + assert.fail(e); + }); +}