Skip to content

Commit 5ba7d7c

Browse files
committed
Fix missing increment in tail parser + tests
1 parent 99fd6b6 commit 5ba7d7c

File tree

4 files changed

+67
-47
lines changed

4 files changed

+67
-47
lines changed

src/better_sqlite3.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -869,14 +869,17 @@ void Statement::JS_new (v8::FunctionCallbackInfo <v8 :: Value> const & info)
869869
tail += 2;
870870
for (char c; (c = *tail); ++tail) {
871871
if (c == '*' && tail[1] == '/') {
872-
tail += 1;
872+
tail += 2;
873873
break;
874874
}
875875
}
876876
} else if (c == '-' && tail[1] == '-') {
877877
tail += 2;
878878
for (char c; (c = *tail); ++tail) {
879-
if (c == '\n') break;
879+
if (c == '\n') {
880+
++tail;
881+
break;
882+
}
880883
}
881884
} else {
882885
sqlite3_finalize(handle);
@@ -895,9 +898,9 @@ void Statement::JS_new (v8::FunctionCallbackInfo <v8 :: Value> const & info)
895898

896899
info.GetReturnValue().Set(info.This());
897900
}
898-
#line 153 "./src/objects/statement.lzz"
901+
#line 156 "./src/objects/statement.lzz"
899902
void Statement::JS_run (v8::FunctionCallbackInfo <v8 :: Value> const & info)
900-
#line 153 "./src/objects/statement.lzz"
903+
#line 156 "./src/objects/statement.lzz"
901904
{
902905
Statement * stmt = node :: ObjectWrap :: Unwrap < Statement > ( info . This ( ) ) ; ( ( void ) 0 ) ; sqlite3_stmt * handle = stmt -> handle ; Database * db = stmt -> db ; if ( ! db -> GetState ( ) -> open ) return ThrowTypeError ( "The database connection is not open" ) ; if ( db -> GetState ( ) -> busy ) return ThrowTypeError ( "This database connection is busy executing a query" ) ; if ( stmt -> locked ) return ThrowTypeError ( "This statement is busy executing a query" ) ; if ( ! db -> GetState ( ) -> unsafe_mode ) { if ( db -> GetState ( ) -> iterators ) return ThrowTypeError ( "This database connection is busy executing a query" ) ; } ( ( void ) 0 ) ; const bool bound = stmt -> bound ; if ( ! bound ) { Binder binder ( handle ) ; if ( ! binder . Bind ( info , info . Length ( ) , stmt ) ) { sqlite3_clear_bindings ( handle ) ; return ; } ( ( void ) 0 ) ; } else if ( info . Length ( ) > 0 ) { return ThrowTypeError ( "This statement already has bound parameters" ) ; } ( ( void ) 0 ) ; db -> GetState ( ) -> busy = true ; v8 :: Isolate * isolate = info . GetIsolate ( ) ; if ( db -> Log ( isolate , handle ) ) { db -> GetState ( ) -> busy = false ; db -> ThrowDatabaseError ( ) ; if ( ! bound ) { sqlite3_clear_bindings ( handle ) ; } return ; } ( ( void ) 0 ) ;
903906
sqlite3* db_handle = db->GetHandle();
@@ -920,9 +923,9 @@ void Statement::JS_run (v8::FunctionCallbackInfo <v8 :: Value> const & info)
920923
}
921924
db -> GetState ( ) -> busy = false ; db -> ThrowDatabaseError ( ) ; if ( ! bound ) { sqlite3_clear_bindings ( handle ) ; } return ;
922925
}
923-
#line 176 "./src/objects/statement.lzz"
926+
#line 179 "./src/objects/statement.lzz"
924927
void Statement::JS_get (v8::FunctionCallbackInfo <v8 :: Value> const & info)
925-
#line 176 "./src/objects/statement.lzz"
928+
#line 179 "./src/objects/statement.lzz"
926929
{
927930
Statement * stmt = node :: ObjectWrap :: Unwrap < Statement > ( info . This ( ) ) ; if ( ! stmt -> returns_data ) return ThrowTypeError ( "This statement does not return data. Use run() instead" ) ; sqlite3_stmt * handle = stmt -> handle ; Database * db = stmt -> db ; if ( ! db -> GetState ( ) -> open ) return ThrowTypeError ( "The database connection is not open" ) ; if ( db -> GetState ( ) -> busy ) return ThrowTypeError ( "This database connection is busy executing a query" ) ; if ( stmt -> locked ) return ThrowTypeError ( "This statement is busy executing a query" ) ; const bool bound = stmt -> bound ; if ( ! bound ) { Binder binder ( handle ) ; if ( ! binder . Bind ( info , info . Length ( ) , stmt ) ) { sqlite3_clear_bindings ( handle ) ; return ; } ( ( void ) 0 ) ; } else if ( info . Length ( ) > 0 ) { return ThrowTypeError ( "This statement already has bound parameters" ) ; } ( ( void ) 0 ) ; db -> GetState ( ) -> busy = true ; v8 :: Isolate * isolate = info . GetIsolate ( ) ; if ( db -> Log ( isolate , handle ) ) { db -> GetState ( ) -> busy = false ; db -> ThrowDatabaseError ( ) ; if ( ! bound ) { sqlite3_clear_bindings ( handle ) ; } return ; } ( ( void ) 0 ) ;
928931
int status = sqlite3_step(handle);
@@ -937,9 +940,9 @@ void Statement::JS_get (v8::FunctionCallbackInfo <v8 :: Value> const & info)
937940
sqlite3_reset(handle);
938941
db -> GetState ( ) -> busy = false ; db -> ThrowDatabaseError ( ) ; if ( ! bound ) { sqlite3_clear_bindings ( handle ) ; } return ;
939942
}
940-
#line 191 "./src/objects/statement.lzz"
943+
#line 194 "./src/objects/statement.lzz"
941944
void Statement::JS_all (v8::FunctionCallbackInfo <v8 :: Value> const & info)
942-
#line 191 "./src/objects/statement.lzz"
945+
#line 194 "./src/objects/statement.lzz"
943946
{
944947
Statement * stmt = node :: ObjectWrap :: Unwrap < Statement > ( info . This ( ) ) ; if ( ! stmt -> returns_data ) return ThrowTypeError ( "This statement does not return data. Use run() instead" ) ; sqlite3_stmt * handle = stmt -> handle ; Database * db = stmt -> db ; if ( ! db -> GetState ( ) -> open ) return ThrowTypeError ( "The database connection is not open" ) ; if ( db -> GetState ( ) -> busy ) return ThrowTypeError ( "This database connection is busy executing a query" ) ; if ( stmt -> locked ) return ThrowTypeError ( "This statement is busy executing a query" ) ; const bool bound = stmt -> bound ; if ( ! bound ) { Binder binder ( handle ) ; if ( ! binder . Bind ( info , info . Length ( ) , stmt ) ) { sqlite3_clear_bindings ( handle ) ; return ; } ( ( void ) 0 ) ; } else if ( info . Length ( ) > 0 ) { return ThrowTypeError ( "This statement already has bound parameters" ) ; } ( ( void ) 0 ) ; db -> GetState ( ) -> busy = true ; v8 :: Isolate * isolate = info . GetIsolate ( ) ; if ( db -> Log ( isolate , handle ) ) { db -> GetState ( ) -> busy = false ; db -> ThrowDatabaseError ( ) ; if ( ! bound ) { sqlite3_clear_bindings ( handle ) ; } return ; } ( ( void ) 0 ) ;
945948
v8 :: Local < v8 :: Context > ctx = isolate -> GetCurrentContext ( ) ;
@@ -960,9 +963,9 @@ void Statement::JS_all (v8::FunctionCallbackInfo <v8 :: Value> const & info)
960963
if (js_error) db->GetState()->was_js_error = true;
961964
db -> GetState ( ) -> busy = false ; db -> ThrowDatabaseError ( ) ; if ( ! bound ) { sqlite3_clear_bindings ( handle ) ; } return ;
962965
}
963-
#line 212 "./src/objects/statement.lzz"
966+
#line 215 "./src/objects/statement.lzz"
964967
void Statement::JS_iterate (v8::FunctionCallbackInfo <v8 :: Value> const & info)
965-
#line 212 "./src/objects/statement.lzz"
968+
#line 215 "./src/objects/statement.lzz"
966969
{
967970
Addon * addon = static_cast < Addon * > ( info . Data ( ) . As < v8 :: External > ( ) -> Value ( ) ) ;
968971
v8 :: Isolate * isolate = info . GetIsolate ( ) ;
@@ -972,9 +975,9 @@ void Statement::JS_iterate (v8::FunctionCallbackInfo <v8 :: Value> const & info)
972975
addon->privileged_info = NULL;
973976
if (!maybeIterator.IsEmpty()) info.GetReturnValue().Set(maybeIterator.ToLocalChecked());
974977
}
975-
#line 222 "./src/objects/statement.lzz"
978+
#line 225 "./src/objects/statement.lzz"
976979
void Statement::JS_bind (v8::FunctionCallbackInfo <v8 :: Value> const & info)
977-
#line 222 "./src/objects/statement.lzz"
980+
#line 225 "./src/objects/statement.lzz"
978981
{
979982
Statement* stmt = node :: ObjectWrap :: Unwrap <Statement>(info.This());
980983
if (stmt->bound) return ThrowTypeError("The bind() method can only be invoked once per statement object");
@@ -985,9 +988,9 @@ void Statement::JS_bind (v8::FunctionCallbackInfo <v8 :: Value> const & info)
985988
stmt->bound = true;
986989
info.GetReturnValue().Set(info.This());
987990
}
988-
#line 233 "./src/objects/statement.lzz"
991+
#line 236 "./src/objects/statement.lzz"
989992
void Statement::JS_pluck (v8::FunctionCallbackInfo <v8 :: Value> const & info)
990-
#line 233 "./src/objects/statement.lzz"
993+
#line 236 "./src/objects/statement.lzz"
991994
{
992995
Statement* stmt = node :: ObjectWrap :: Unwrap <Statement>(info.This());
993996
if (!stmt->returns_data) return ThrowTypeError("The pluck() method is only for statements that return data");
@@ -998,9 +1001,9 @@ void Statement::JS_pluck (v8::FunctionCallbackInfo <v8 :: Value> const & info)
9981001
stmt->mode = use ? Data::PLUCK : stmt->mode == Data::PLUCK ? Data::FLAT : stmt->mode;
9991002
info.GetReturnValue().Set(info.This());
10001003
}
1001-
#line 244 "./src/objects/statement.lzz"
1004+
#line 247 "./src/objects/statement.lzz"
10021005
void Statement::JS_expand (v8::FunctionCallbackInfo <v8 :: Value> const & info)
1003-
#line 244 "./src/objects/statement.lzz"
1006+
#line 247 "./src/objects/statement.lzz"
10041007
{
10051008
Statement* stmt = node :: ObjectWrap :: Unwrap <Statement>(info.This());
10061009
if (!stmt->returns_data) return ThrowTypeError("The expand() method is only for statements that return data");
@@ -1011,9 +1014,9 @@ void Statement::JS_expand (v8::FunctionCallbackInfo <v8 :: Value> const & info)
10111014
stmt->mode = use ? Data::EXPAND : stmt->mode == Data::EXPAND ? Data::FLAT : stmt->mode;
10121015
info.GetReturnValue().Set(info.This());
10131016
}
1014-
#line 255 "./src/objects/statement.lzz"
1017+
#line 258 "./src/objects/statement.lzz"
10151018
void Statement::JS_raw (v8::FunctionCallbackInfo <v8 :: Value> const & info)
1016-
#line 255 "./src/objects/statement.lzz"
1019+
#line 258 "./src/objects/statement.lzz"
10171020
{
10181021
Statement* stmt = node :: ObjectWrap :: Unwrap <Statement>(info.This());
10191022
if (!stmt->returns_data) return ThrowTypeError("The raw() method is only for statements that return data");
@@ -1024,9 +1027,9 @@ void Statement::JS_raw (v8::FunctionCallbackInfo <v8 :: Value> const & info)
10241027
stmt->mode = use ? Data::RAW : stmt->mode == Data::RAW ? Data::FLAT : stmt->mode;
10251028
info.GetReturnValue().Set(info.This());
10261029
}
1027-
#line 266 "./src/objects/statement.lzz"
1030+
#line 269 "./src/objects/statement.lzz"
10281031
void Statement::JS_safeIntegers (v8::FunctionCallbackInfo <v8 :: Value> const & info)
1029-
#line 266 "./src/objects/statement.lzz"
1032+
#line 269 "./src/objects/statement.lzz"
10301033
{
10311034
Statement* stmt = node :: ObjectWrap :: Unwrap <Statement>(info.This());
10321035
if ( stmt -> db -> GetState ( ) -> busy ) return ThrowTypeError ( "This database connection is busy executing a query" ) ;
@@ -1035,9 +1038,9 @@ void Statement::JS_safeIntegers (v8::FunctionCallbackInfo <v8 :: Value> const &
10351038
else { if ( info . Length ( ) <= ( 0 ) || ! info [ 0 ] -> IsBoolean ( ) ) return ThrowTypeError ( "Expected " "first" " argument to be " "a boolean" ) ; stmt -> safe_ints = ( info [ 0 ] . As < v8 :: Boolean > ( ) ) -> Value ( ) ; }
10361039
info.GetReturnValue().Set(info.This());
10371040
}
1038-
#line 275 "./src/objects/statement.lzz"
1041+
#line 278 "./src/objects/statement.lzz"
10391042
void Statement::JS_columns (v8::FunctionCallbackInfo <v8 :: Value> const & info)
1040-
#line 275 "./src/objects/statement.lzz"
1043+
#line 278 "./src/objects/statement.lzz"
10411044
{
10421045
Statement* stmt = node :: ObjectWrap :: Unwrap <Statement>(info.This());
10431046
if (!stmt->returns_data) return ThrowTypeError("The columns() method is only for statements that return data");
@@ -1080,9 +1083,9 @@ void Statement::JS_columns (v8::FunctionCallbackInfo <v8 :: Value> const & info)
10801083

10811084
info.GetReturnValue().Set(columns);
10821085
}
1083-
#line 318 "./src/objects/statement.lzz"
1086+
#line 321 "./src/objects/statement.lzz"
10841087
void Statement::JS_busy (v8::Local <v8 :: String> _, v8::PropertyCallbackInfo <v8 :: Value> const & info)
1085-
#line 318 "./src/objects/statement.lzz"
1088+
#line 321 "./src/objects/statement.lzz"
10861089
{
10871090
Statement* stmt = node :: ObjectWrap :: Unwrap <Statement>(info.This());
10881091
info.GetReturnValue().Set(stmt->alive && stmt->locked);

src/better_sqlite3.hpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -340,47 +340,47 @@ class Statement : public node::ObjectWrap
340340
explicit Statement (Database * db, sqlite3_stmt * handle, sqlite3_uint64 id, bool returns_data);
341341
#line 85 "./src/objects/statement.lzz"
342342
static void JS_new (v8::FunctionCallbackInfo <v8 :: Value> const & info);
343-
#line 153 "./src/objects/statement.lzz"
343+
#line 156 "./src/objects/statement.lzz"
344344
static void JS_run (v8::FunctionCallbackInfo <v8 :: Value> const & info);
345-
#line 176 "./src/objects/statement.lzz"
345+
#line 179 "./src/objects/statement.lzz"
346346
static void JS_get (v8::FunctionCallbackInfo <v8 :: Value> const & info);
347-
#line 191 "./src/objects/statement.lzz"
347+
#line 194 "./src/objects/statement.lzz"
348348
static void JS_all (v8::FunctionCallbackInfo <v8 :: Value> const & info);
349-
#line 212 "./src/objects/statement.lzz"
349+
#line 215 "./src/objects/statement.lzz"
350350
static void JS_iterate (v8::FunctionCallbackInfo <v8 :: Value> const & info);
351-
#line 222 "./src/objects/statement.lzz"
351+
#line 225 "./src/objects/statement.lzz"
352352
static void JS_bind (v8::FunctionCallbackInfo <v8 :: Value> const & info);
353-
#line 233 "./src/objects/statement.lzz"
353+
#line 236 "./src/objects/statement.lzz"
354354
static void JS_pluck (v8::FunctionCallbackInfo <v8 :: Value> const & info);
355-
#line 244 "./src/objects/statement.lzz"
355+
#line 247 "./src/objects/statement.lzz"
356356
static void JS_expand (v8::FunctionCallbackInfo <v8 :: Value> const & info);
357-
#line 255 "./src/objects/statement.lzz"
357+
#line 258 "./src/objects/statement.lzz"
358358
static void JS_raw (v8::FunctionCallbackInfo <v8 :: Value> const & info);
359-
#line 266 "./src/objects/statement.lzz"
359+
#line 269 "./src/objects/statement.lzz"
360360
static void JS_safeIntegers (v8::FunctionCallbackInfo <v8 :: Value> const & info);
361-
#line 275 "./src/objects/statement.lzz"
361+
#line 278 "./src/objects/statement.lzz"
362362
static void JS_columns (v8::FunctionCallbackInfo <v8 :: Value> const & info);
363-
#line 318 "./src/objects/statement.lzz"
363+
#line 321 "./src/objects/statement.lzz"
364364
static void JS_busy (v8::Local <v8 :: String> _, v8::PropertyCallbackInfo <v8 :: Value> const & info);
365-
#line 323 "./src/objects/statement.lzz"
365+
#line 326 "./src/objects/statement.lzz"
366366
Database * const db;
367-
#line 324 "./src/objects/statement.lzz"
367+
#line 327 "./src/objects/statement.lzz"
368368
sqlite3_stmt * const handle;
369-
#line 325 "./src/objects/statement.lzz"
369+
#line 328 "./src/objects/statement.lzz"
370370
Extras * const extras;
371-
#line 326 "./src/objects/statement.lzz"
371+
#line 329 "./src/objects/statement.lzz"
372372
bool alive;
373-
#line 327 "./src/objects/statement.lzz"
373+
#line 330 "./src/objects/statement.lzz"
374374
bool locked;
375-
#line 328 "./src/objects/statement.lzz"
375+
#line 331 "./src/objects/statement.lzz"
376376
bool bound;
377-
#line 329 "./src/objects/statement.lzz"
377+
#line 332 "./src/objects/statement.lzz"
378378
bool has_bind_map;
379-
#line 330 "./src/objects/statement.lzz"
379+
#line 333 "./src/objects/statement.lzz"
380380
bool safe_ints;
381-
#line 331 "./src/objects/statement.lzz"
381+
#line 334 "./src/objects/statement.lzz"
382382
char mode;
383-
#line 332 "./src/objects/statement.lzz"
383+
#line 335 "./src/objects/statement.lzz"
384384
bool const returns_data;
385385
};
386386
#line 1 "./src/objects/statement-iterator.lzz"

src/objects/statement.lzz

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,17 @@ private:
123123
tail += 2;
124124
for (char c; (c = *tail); ++tail) {
125125
if (c == '*' && tail[1] == '/') {
126-
tail += 1;
126+
tail += 2;
127127
break;
128128
}
129129
}
130130
} else if (c == '-' && tail[1] == '-') {
131131
tail += 2;
132132
for (char c; (c = *tail); ++tail) {
133-
if (c == '\n') break;
133+
if (c == '\n') {
134+
++tail;
135+
break;
136+
}
134137
}
135138
} else {
136139
sqlite3_finalize(handle);

test/13.database.prepare.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ describe('Database#prepare()', function () {
3737
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);CREATE TABLE animals (name TEXT)')).to.throw(RangeError);
3838
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);/')).to.throw(RangeError);
3939
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);-')).to.throw(RangeError);
40+
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);--\n/;')).to.throw(RangeError);
41+
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);--\nSELECT 123;')).to.throw(RangeError);
42+
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);-- comment\nSELECT 123;')).to.throw(RangeError);
43+
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);/**/-')).to.throw(RangeError);
44+
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);/**/SELECT 123;')).to.throw(RangeError);
45+
expect(() => this.db.prepare('CREATE TABLE people (name TEXT);/* comment */SELECT 123;')).to.throw(RangeError);
4046
});
4147
it('should create a prepared Statement object', function () {
4248
const stmt1 = this.db.prepare('CREATE TABLE people (name TEXT) ');
@@ -57,4 +63,12 @@ describe('Database#prepare()', function () {
5763
assertStmt(this.db.prepare('BEGIN EXCLUSIVE'), 'BEGIN EXCLUSIVE', this.db, false, false);
5864
assertStmt(this.db.prepare('DELETE FROM data RETURNING *'), 'DELETE FROM data RETURNING *', this.db, true, false);
5965
});
66+
it('should create a prepared Statement object ignoring trailing comments and whitespace', function () {
67+
assertStmt(this.db.prepare('SELECT 555; '), 'SELECT 555; ', this.db, true, true);
68+
assertStmt(this.db.prepare('SELECT 555;-- comment'), 'SELECT 555;-- comment', this.db, true, true);
69+
assertStmt(this.db.prepare('SELECT 555;--abc\n--de\n--f'), 'SELECT 555;--abc\n--de\n--f', this.db, true, true);
70+
assertStmt(this.db.prepare('SELECT 555;/* comment */'), 'SELECT 555;/* comment */', this.db, true, true);
71+
assertStmt(this.db.prepare('SELECT 555;/* comment */-- comment'), 'SELECT 555;/* comment */-- comment', this.db, true, true);
72+
assertStmt(this.db.prepare('SELECT 555;-- comment\n/* comment */'), 'SELECT 555;-- comment\n/* comment */', this.db, true, true);
73+
});
6074
});

0 commit comments

Comments
 (0)