SQLite

Check-in [183c236e99]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a crash that can follow an OOM when "all tables" are registered with a session module.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 183c236e991faaabdc768e52e926c52cf4a7abc9
User & Date: dan 2011-03-22 16:54:12.000
Context
2011-03-22
18:45
Add API function sqlite3_preupdate_depth(), for determining the depth of the trigger stack from within a pre-update callback. (check-in: bdea70895c user: dan tags: sessions)
16:54
Fix a crash that can follow an OOM when "all tables" are registered with a session module. (check-in: 183c236e99 user: dan tags: sessions)
15:21
If a NULL pointer is passed to sqlite3session_attach() in place of a table name, attach all database tables to the session object. (check-in: e9037e4e4c user: dan tags: sessions)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/session/sessionfault.test.
30
31
32
33
34
35
36




37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52


























53
54
55
56
57
58
59
faultsim_save_and_close
db2 close


#-------------------------------------------------------------------------
# Test OOM error handling when collecting and applying a simple changeset.
#




do_faultsim_test pagerfault-1 -faults oom-* -prep {
  catch {db2 close}
  catch {db close}
  faultsim_restore_and_reopen
  sqlite3 db2 test.db2
} -body {
  do_then_apply_sql {
    INSERT INTO t1 VALUES(7, 8, 9);
    UPDATE t1 SET c = 10 WHERE a = 1;
    DELETE FROM t1 WHERE a = 4;
  }
} -test {
  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  faultsim_integrity_check
  if {$testrc==0} { compare_db db db2 }
}



























#-------------------------------------------------------------------------
# The following block of tests - pagerfault-2.* - are designed to check 
# the handling of faults in the sqlite3changeset_apply() function.
#
catch {db close}
catch {db2 close}







>
>
>
>
|















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
faultsim_save_and_close
db2 close


#-------------------------------------------------------------------------
# Test OOM error handling when collecting and applying a simple changeset.
#
# Test 1.1 attaches tables individually by name to the session object. 
# Whereas test 1.2 passes NULL to sqlite3session_attach() to attach all
# tables.
#
do_faultsim_test pagerfault-1.1 -faults oom-* -prep {
  catch {db2 close}
  catch {db close}
  faultsim_restore_and_reopen
  sqlite3 db2 test.db2
} -body {
  do_then_apply_sql {
    INSERT INTO t1 VALUES(7, 8, 9);
    UPDATE t1 SET c = 10 WHERE a = 1;
    DELETE FROM t1 WHERE a = 4;
  }
} -test {
  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  faultsim_integrity_check
  if {$testrc==0} { compare_db db db2 }
}

do_faultsim_test pagerfault-1.2 -faults oom-* -prep {
  catch {db2 close}
  catch {db close}
  faultsim_restore_and_reopen
} -body {
  sqlite3session S db main
  S attach *
  execsql {
    INSERT INTO t1 VALUES(7, 8, 9);
    UPDATE t1 SET c = 10 WHERE a = 1;
    DELETE FROM t1 WHERE a = 4;
  }
  set ::changeset [S changeset]
  set {} {}
} -test {
  catch { S delete }
  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  faultsim_integrity_check
  if {$testrc==0} { 
    proc xConflict {args} { return "OMIT" }
    sqlite3 db2 test.db2
    sqlite3changeset_apply db2 $::changeset xConflict
    compare_db db db2 
  }
}

#-------------------------------------------------------------------------
# The following block of tests - pagerfault-2.* - are designed to check 
# the handling of faults in the sqlite3changeset_apply() function.
#
catch {db close}
catch {db2 close}
Changes to ext/session/sqlite3session.c.
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
    if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;

    for(pTab=pSession->pTable; pTab || pSession->bAutoAttach; pTab=pTab->pNext){
      if( !pTab ){
        /* This branch is taken if table zName has not yet been attached to
        ** this session and the auto-attach flag is set.  */
        pSession->rc = sqlite3session_attach(pSession,zName);
        if( pSession->rc ) continue;
        pTab = pSession->pTable;
        assert( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) );
      }

      if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){
        sessionPreupdateOneChange(op, pSession, pTab);
        if( op==SQLITE_UPDATE ){







|







777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
    if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;

    for(pTab=pSession->pTable; pTab || pSession->bAutoAttach; pTab=pTab->pNext){
      if( !pTab ){
        /* This branch is taken if table zName has not yet been attached to
        ** this session and the auto-attach flag is set.  */
        pSession->rc = sqlite3session_attach(pSession,zName);
        if( pSession->rc ) break;
        pTab = pSession->pTable;
        assert( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) );
      }

      if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){
        sessionPreupdateOneChange(op, pSession, pTab);
        if( op==SQLITE_UPDATE ){