System.Data.SQLite

Check-in [e877217109]
Login

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

Overview
Comment:When using the (unsupported) legacy CryptoAPI based codec, skip encrypting page #1 because that can lead to database corruption and other malfunctions.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e8772171097e9db19d82eeea30035999aba94876
User & Date: mistachkin 2020-03-04 03:25:41.197
References
2020-04-03
18:21
Partial cherrypick of [e87721710]. check-in: 93e22965f8 user: mistachkin tags: branch-1.0.112
Context
2020-05-24
00:36
Get this branch up-to-date with most trunk changes. check-in: bf714af93b user: mistachkin tags: branch-1.0.112
2020-04-03
18:21
Partial cherrypick of [e87721710]. check-in: 93e22965f8 user: mistachkin tags: branch-1.0.112
2020-03-04
03:31
Fix typos in comments. check-in: 4194e07323 user: mistachkin tags: trunk
03:25
When using the (unsupported) legacy CryptoAPI based codec, skip encrypting page #1 because that can lead to database corruption and other malfunctions. check-in: e877217109 user: mistachkin tags: trunk
02:04
Update several test cases. check-in: 8fa881a525 user: mistachkin tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Doc/Extra/Provider/environment.html.
261
262
263
264
265
266
267










268
269
270
271
272
273
274
          <td>PROCESSOR_ARCHITECTURE</td>
          <td>This environment variable is normally set by the operating
          system itself and should reflect the native processor architecture
          of the current process (e.g. a 32-bit x86 application running on a
          64-bit x64 operating system should have the value &quot;x86&quot;).
          </td>
        </tr>










        <tr valign="top">
          <td>SQLite_ForceLogPrepare</td>
          <td>If this environment variable is set [to anything], all calls to
          prepare a SQL query will be logged, regardless of the flags for the
          associated connection.</td>
        </tr>
        <tr valign="top">







>
>
>
>
>
>
>
>
>
>







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
          <td>PROCESSOR_ARCHITECTURE</td>
          <td>This environment variable is normally set by the operating
          system itself and should reflect the native processor architecture
          of the current process (e.g. a 32-bit x86 application running on a
          64-bit x64 operating system should have the value &quot;x86&quot;).
          </td>
        </tr>
        <tr valign="top">
          <td>SQLite_EncryptPage1</td>
          <td>If this environment variable is set [to anything], page #1 of
          databases encrypted using the (unsupported) legacy CryptoAPI codec
          files will be encrypted.  This was the default behavior prior to
          release 1.0.113.0; however, it is now disabled (by default) as it
          can cause corruption and/or other malfunctions in some circumstances.
          Please do not use this environment variable unless it is absolutely
          necessary for your specific use case.</td>
        </tr>
        <tr valign="top">
          <td>SQLite_ForceLogPrepare</td>
          <td>If this environment variable is set [to anything], all calls to
          prepare a SQL query will be logged, regardless of the flags for the
          associated connection.</td>
        </tr>
        <tr valign="top">
Changes to Doc/Extra/Provider/version.html.
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
    <h1 class="heading">Version History</h1>
    <p><b>1.0.113.0 - February XX, 2020 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_31_1.html">SQLite 3.31.1</a>.</li>
      <li>Include the &quot;LINQ&quot; partial classes in the primary managed assembly for .NET Standard 2.1. Fix for <a href="https://system.data.sqlite.org/index.html/info/ad28d8e026">[ad28d8e026]</a>.</li>
      <li>Add SQLite_ForceLogLifecycle environment variable to force logging of calls into key members pertaining to the lifecycle of connections and their associated classes (e.g. LINQ, EF6, etc).</li>

    </ul>
    <p><b>1.0.112.0 - October 28, 2019</b></p>
    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_30_1.html">SQLite 3.30.1</a>.</li>
      <li>Add preliminary support for .NET Core 3.0 and the .NET Standard 2.1. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/ce75d320d0">[ce75d320d0]</a>.</li>
      <li>Updated to <a href="https://www.nuget.org/packages/EntityFramework/6.3.0">Entity Framework 6.3.0</a>.</li>
      <li>Add support for new DBCONFIG options from the SQLite core library. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/03b6b0edd7">[03b6b0edd7]</a>.</li>







|




>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
    <h1 class="heading">Version History</h1>
    <p><b>1.0.113.0 - March XX, 2020 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_31_1.html">SQLite 3.31.1</a>.</li>
      <li>Include the &quot;LINQ&quot; partial classes in the primary managed assembly for .NET Standard 2.1. Fix for <a href="https://system.data.sqlite.org/index.html/info/ad28d8e026">[ad28d8e026]</a>.</li>
      <li>Add SQLite_ForceLogLifecycle environment variable to force logging of calls into key members pertaining to the lifecycle of connections and their associated classes (e.g. LINQ, EF6, etc).</li>
      <li>When using the (unsupported) legacy CryptoAPI based codec, skip encrypting page #1 because that can lead to database corruption and other malfunctions.</li>
    </ul>
    <p><b>1.0.112.0 - October 28, 2019</b></p>
    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_30_1.html">SQLite 3.30.1</a>.</li>
      <li>Add preliminary support for .NET Core 3.0 and the .NET Standard 2.1. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/ce75d320d0">[ce75d320d0]</a>.</li>
      <li>Updated to <a href="https://www.nuget.org/packages/EntityFramework/6.3.0">Entity Framework 6.3.0</a>.</li>
      <li>Add support for new DBCONFIG options from the SQLite core library. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/03b6b0edd7">[03b6b0edd7]</a>.</li>
Changes to SQLite.Interop/src/win/crypt.c.
20
21
22
23
24
25
26






27
28
29
30
31
32
33
  HCRYPTKEY hReadKey;     /* Key used to read from the database and write to the journal */
  HCRYPTKEY hWriteKey;    /* Key used to write to the database */
  DWORD     dwPageSize;   /* Size of pages */
  LPVOID    pvCrypt;      /* A buffer for encrypting/decrypting (if necessary) */
  DWORD     dwCryptSize;  /* Equal to or greater than dwPageSize.  If larger, pvCrypt is valid and this is its size */
} CRYPTBLOCK, *LPCRYPTBLOCK;







HCRYPTPROV g_hProvider = 0; /* Global instance of the cryptographic provider */

#define SQLITECRYPTERROR_PROVIDER "Cryptographic provider not available"

/* Needed for re-keying */
static void * sqlite3pager_get_codecarg(Pager *pPager)
{







>
>
>
>
>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  HCRYPTKEY hReadKey;     /* Key used to read from the database and write to the journal */
  HCRYPTKEY hWriteKey;    /* Key used to write to the database */
  DWORD     dwPageSize;   /* Size of pages */
  LPVOID    pvCrypt;      /* A buffer for encrypting/decrypting (if necessary) */
  DWORD     dwCryptSize;  /* Equal to or greater than dwPageSize.  If larger, pvCrypt is valid and this is its size */
} CRYPTBLOCK, *LPCRYPTBLOCK;

#define CRYPT_PAGE1_UNKNOWN  (0)
#define CRYPT_PAGE1_ENABLED  (1)
#define CRYPT_PAGE1_DISABLED (2)

BOOL g_bEncryptPage1 = CRYPT_PAGE1_UNKNOWN;

HCRYPTPROV g_hProvider = 0; /* Global instance of the cryptographic provider */

#define SQLITECRYPTERROR_PROVIDER "Cryptographic provider not available"

/* Needed for re-keying */
static void * sqlite3pager_get_codecarg(Pager *pPager)
{
149
150
151
152
153
154
155
156













157


















158
159
160
161
162
163
164

/* Encrypt/Decrypt functionality, called by pager.c */
static void *sqlite3Codec(void *pArg, void *data, Pgno nPageNum, int nMode)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;
  DWORD dwPageSize;
  LPVOID pvTemp = NULL;














  if (!pBlock) return data;


















  if (pBlock->pvCrypt == NULL) return NULL; /* This only happens if CreateCryptBlock() failed to make scratch space */

  switch(nMode)
  {
  case 0: /* Undo a "case 7" journal file encryption */
  case 2: /* Reload a page */
  case 3: /* Load a page */








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

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







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

/* Encrypt/Decrypt functionality, called by pager.c */
static void *sqlite3Codec(void *pArg, void *data, Pgno nPageNum, int nMode)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;
  DWORD dwPageSize;
  LPVOID pvTemp = NULL;

  if (g_bEncryptPage1 == CRYPT_PAGE1_UNKNOWN)
  {
    WCHAR aBuf[2];
    memset(aBuf, 0, sizeof(aBuf));
    if ((GetEnvironmentVariableW(L"SQLite_EncryptPage1", aBuf, sizeof(aBuf)) != 0)
     || (GetLastError() != ERROR_ENVVAR_NOT_FOUND))
    {
      g_bEncryptPage1 = CRYPT_PAGE1_ENABLED;
    } else {
      g_bEncryptPage1 = CRYPT_PAGE1_DISABLED;
    }
  }

  if (!pBlock) return data;
  if (g_bEncryptPage1 == CRYPT_PAGE1_DISABLED)
  {
    if (nPageNum == 1) // BUGFIX: Skip first page as it contains metadata
                       //         necessary to initialize the pager.  For
                       //         backward compatibility, decrypt page #1
                       //         for any existing databases.
    {
      //
      // NOTE: If this is page #1 and it starts with the file header, it
      //       should not be encrypted; so, do nothing to it; otherwise,
      //       it is encrypted and must be decrypted.
      //
      if (memcmp(data, zMagicHeader, sizeof(zMagicHeader)) == 0)
      {
        return data;
      }
    }
  }
  if (pBlock->pvCrypt == NULL) return NULL; /* This only happens if CreateCryptBlock() failed to make scratch space */

  switch(nMode)
  {
  case 0: /* Undo a "case 7" journal file encryption */
  case 2: /* Reload a page */
  case 3: /* Load a page */
Changes to System.Data.SQLite/Configurations/System.Data.SQLite.dll.config.
251
252
253
254
255
256
257


















258
259
260
261
262
263
264
              architecture of the current process (e.g. a 32-bit x86
              application running on a 64-bit x64 operating system should have
              the value "x86").
    -->
    <!--
    <add key="PROCESSOR_ARCHITECTURE" value="%PROCESSOR_ARCHITECTURE%" />
    -->



















    <!--
        NOTE: If this environment variable is set [to anything], all calls to
              prepare a SQL query will be logged, regardless of the flags for
              the associated connection.
    -->
    <!--







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







251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
              architecture of the current process (e.g. a 32-bit x86
              application running on a 64-bit x64 operating system should have
              the value "x86").
    -->
    <!--
    <add key="PROCESSOR_ARCHITECTURE" value="%PROCESSOR_ARCHITECTURE%" />
    -->

    <!--
        NOTE: If this environment variable is set [to anything], page #1 of
              databases encrypted using the (unsupported) legacy CryptoAPI
              codec files will be encrypted.  This was the default behavior
              prior to release 1.0.113.0; however, it is now disabled (by
              default) as it can cause corruption and/or other malfunctions
              in some circumstances.  Please do not use this environment
              variable unless it is absolutely necessary for your specific
              use case.

        NOTE: Since this environment variable is read from the native interop
              assembly, it cannot be set via this configuration file.  It can
              only be set within the process environment.
    -->
    <!--
    <add key="SQLite_EncryptPage1" value="1" />
    -->

    <!--
        NOTE: If this environment variable is set [to anything], all calls to
              prepare a SQL query will be logged, regardless of the flags for
              the associated connection.
    -->
    <!--
Changes to Tests/basic.eagle.
2064
2065
2066
2067
2068
2069
2070








2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
  setupDb $fileName "" "" "" "" "Password= 1234;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error









  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}

###############################################################################

runTest {test data-1.42 {encrypted database, w/quoted-start-space} -setup {
  setupDb [set fileName data-1.42.db] "" "" "" "" "Password=\" 1234\";"
} -body {
  sql execute $db "CREATE TABLE t1(x);"







>
>
>
>
>
>
>
>







|







2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
  setupDb $fileName "" "" "" "" "Password= 1234;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  cleanupDb $fileName db true false false

  lappend result [expr {
      [haveConstraint System.Data.SQLite.SEE] || [string equal \
      [readDbFileHeader [file join [getDatabaseDirectory] $fileName]] \
      [getDbFileHeader]] == ![info exists env(SQLite_EncryptPage1)]
  }]

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3 True}}

###############################################################################

runTest {test data-1.42 {encrypted database, w/quoted-start-space} -setup {
  setupDb [set fileName data-1.42.db] "" "" "" "" "Password=\" 1234\";"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
2184
2185
2186
2187
2188
2189
2190








2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
  setupDb $fileName "" "" "" "" "Password=1234 ;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error









  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}

###############################################################################

runTest {test data-1.45 {encrypted database, w/quoted-end-space} -setup {
  setupDb [set fileName data-1.45.db] "" "" "" "" "Password=\"1234 \";"
} -body {
  sql execute $db "CREATE TABLE t1(x);"







>
>
>
>
>
>
>
>







|







2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
  setupDb $fileName "" "" "" "" "Password=1234 ;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  cleanupDb $fileName db true false false

  lappend result [expr {
      [haveConstraint System.Data.SQLite.SEE] || [string equal \
      [readDbFileHeader [file join [getDatabaseDirectory] $fileName]] \
      [getDbFileHeader]] == ![info exists env(SQLite_EncryptPage1)]
  }]

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3 True}}

###############################################################################

runTest {test data-1.45 {encrypted database, w/quoted-end-space} -setup {
  setupDb [set fileName data-1.45.db] "" "" "" "" "Password=\"1234 \";"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
2275
2276
2277
2278
2279
2280
2281








2282
2283
2284
2285
2286
2287
2288
2289
2290
2291

2292
2293
2294
2295
2296
2297
2298
  setupDb $fileName "" "" "" "" "Password=\"67 89\";" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error









  set result
} -cleanup {
  unset -nocomplain connection

  cleanupDb $fileName; # NOTE: After object disposal.

  unset -nocomplain connectionStringBuilder error result db fileName
} -constraints {eagle command.object System.Data.SQLite.Encryption monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}


###############################################################################

runTest {test data-1.47 {quoted connection string properties} -setup {
  unset -nocomplain result list pair strings string
} -body {
  set result [list]







>
>
>
>
>
>
>
>









|
>







2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
  setupDb $fileName "" "" "" "" "Password=\"67 89\";" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  cleanupDb $fileName db true false false

  lappend result [expr {
      [haveConstraint System.Data.SQLite.SEE] || [string equal \
      [readDbFileHeader [file join [getDatabaseDirectory] $fileName]] \
      [getDbFileHeader]] == ![info exists env(SQLite_EncryptPage1)]
  }]

  set result
} -cleanup {
  unset -nocomplain connection

  cleanupDb $fileName; # NOTE: After object disposal.

  unset -nocomplain connectionStringBuilder error result db fileName
} -constraints {eagle command.object System.Data.SQLite.Encryption monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -result \
{0 1 0 1 0 1 0 3 True}}

###############################################################################

runTest {test data-1.47 {quoted connection string properties} -setup {
  unset -nocomplain result list pair strings string
} -body {
  set result [list]
Changes to Tests/tkt-1c456ae75f.eagle.
84
85
86
87
88
89
90








91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
  setupDb $fileName "" "" "" "" "HexPassword=3132333435;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error









  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}

###############################################################################

runTest {test tkt-1c456ae75f-1.3 {database, wrong hex password} -setup {
  setupDb [set fileName tkt-1c456ae75f-1.3.db] "" "" "" "" \
      "HexPassword=3132333435;"
} -body {







>
>
>
>
>
>
>
>







|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  setupDb $fileName "" "" "" "" "HexPassword=3132333435;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  cleanupDb $fileName db true false false

  lappend result [expr {
      [haveConstraint System.Data.SQLite.SEE] || [string equal \
      [readDbFileHeader [file join [getDatabaseDirectory] $fileName]] \
      [getDbFileHeader]] == ![info exists env(SQLite_EncryptPage1)]
  }]

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3 True}}

###############################################################################

runTest {test tkt-1c456ae75f-1.3 {database, wrong hex password} -setup {
  setupDb [set fileName tkt-1c456ae75f-1.3.db] "" "" "" "" \
      "HexPassword=3132333435;"
} -body {
177
178
179
180
181
182
183








184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
  setupDb $fileName "" "" "" "" "Password=\"12345\";" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error









  set result
} -cleanup {
  unset -nocomplain connection

  cleanupDb $fileName; # NOTE: After object disposal.

  unset -nocomplain connectionStringBuilder error result db fileName
} -constraints {eagle command.object System.Data.SQLite.Encryption monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}


###############################################################################

runSQLiteTestEpilogue
runTestEpilogue







>
>
>
>
>
>
>
>









|
>





185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
  setupDb $fileName "" "" "" "" "Password=\"12345\";" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  cleanupDb $fileName db true false false

  lappend result [expr {
      [haveConstraint System.Data.SQLite.SEE] || [string equal \
      [readDbFileHeader [file join [getDatabaseDirectory] $fileName]] \
      [getDbFileHeader]] == ![info exists env(SQLite_EncryptPage1)]
  }]

  set result
} -cleanup {
  unset -nocomplain connection

  cleanupDb $fileName; # NOTE: After object disposal.

  unset -nocomplain connectionStringBuilder error result db fileName
} -constraints {eagle command.object System.Data.SQLite.Encryption monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -result \
{0 1 0 1 0 1 0 3 True}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to lib/System.Data.SQLite/common.eagle.
3016
3017
3018
3019
3020
3021
3022













3023
3024
3025
3026
3027
3028
3029
        if {!$quiet} then {
          tputs $channel [appendArgs \
              "---- call sqlite3_enable_shared_cache(" $enable \
              ")... error: " \n\t $result \n]
        }
      }
    }














    proc setupDb {
            fileName {mode ""} {dateTimeFormat ""} {dateTimeKind ""} {flags ""}
            {extra ""} {qualify true} {delete true} {uri false}
            {temporary true} {varName db} {quiet false} } {
      #
      # NOTE: First, see if our caller has requested an in-memory database.







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







3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
        if {!$quiet} then {
          tputs $channel [appendArgs \
              "---- call sqlite3_enable_shared_cache(" $enable \
              ")... error: " \n\t $result \n]
        }
      }
    }

    proc getDbFileHeader {} {
      return "SQLite format 3\0"
    }

    proc readDbFileHeader { fileName } {
      set channel [open $fileName RDONLY]
      makeBinaryChannel $channel
      set header [getDbFileHeader]
      set result [read $channel [string length $header]]
      close $channel
      return $result
    }

    proc setupDb {
            fileName {mode ""} {dateTimeFormat ""} {dateTimeKind ""} {flags ""}
            {extra ""} {qualify true} {delete true} {uri false}
            {temporary true} {varName db} {quiet false} } {
      #
      # NOTE: First, see if our caller has requested an in-memory database.
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670













5671
5672
5673
5674
5675
5676
5677
          #
          # NOTE: Now check if the interop assembly was also compiled with
          #       support for encrypted databases.
          #
          if {[haveSQLiteCompileOption CODEC] || \
              [haveSQLiteCompileOption INCLUDE_SEE]} then {
            #
            # NOTE: Finally, check if the SQLite core library was compiled
            #       with support for encrypted databases.
            #
            if {[haveSQLiteCompileOption HAS_CODEC]} then {
              #
              # NOTE: Yes, add constraint for use by the test suite.
              #
              addConstraint System.Data.SQLite.Encryption













            }
          }
        }

        #
        # NOTE: Try to setup an interrupt callback using the script debugger
        #       that will cancel all SQL queries in progress for all database







|







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







5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
          #
          # NOTE: Now check if the interop assembly was also compiled with
          #       support for encrypted databases.
          #
          if {[haveSQLiteCompileOption CODEC] || \
              [haveSQLiteCompileOption INCLUDE_SEE]} then {
            #
            # NOTE: Next, check if the SQLite core library was compiled
            #       with support for encrypted databases.
            #
            if {[haveSQLiteCompileOption HAS_CODEC]} then {
              #
              # NOTE: Yes, add constraint for use by the test suite.
              #
              addConstraint System.Data.SQLite.Encryption

              #
              # NOTE: Next, chck if the SQLite core library was compiled
              #       with SEE.
              #
              if {[haveSQLiteDefineConstant INTEROP_INCLUDE_SEE] && \
                  [haveSQLiteCompileOption INCLUDE_SEE]} then {
                #
                # NOTE: Finally, when compiled with SEE, add the
                #       appropriate constraint.
                #
                addConstraint System.Data.SQLite.SEE
              }
            }
          }
        }

        #
        # NOTE: Try to setup an interrupt callback using the script debugger
        #       that will cancel all SQL queries in progress for all database
Changes to readme.htm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
ADO.NET SQLite Data Provider<br />
Version 1.0.113.0 - February XX, 2020 <font color="red">(release scheduled)</font><br />
Using <a href="https://www.sqlite.org/releaselog/3_31_1.html">SQLite 3.31.1</a><br />Originally written by Robert Simpson<br />
Released to the public domain, use at your own risk!<br />
Official provider website:&nbsp;<a href="https://system.data.sqlite.org/">https://system.data.sqlite.org/</a><br />
Legacy versions:&nbsp;<a href="https://sourceforge.net/projects/sqlite-dotnet2/">https://sourceforge.net/projects/sqlite-dotnet2/</a><br />
<br />
The current development version can be downloaded from <a href="https://system.data.sqlite.org/index.html/timeline?y=ci">
https://system.data.sqlite.org/index.html/timeline?y=ci</a>







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
ADO.NET SQLite Data Provider<br />
Version 1.0.113.0 - March XX, 2020 <font color="red">(release scheduled)</font><br />
Using <a href="https://www.sqlite.org/releaselog/3_31_1.html">SQLite 3.31.1</a><br />Originally written by Robert Simpson<br />
Released to the public domain, use at your own risk!<br />
Official provider website:&nbsp;<a href="https://system.data.sqlite.org/">https://system.data.sqlite.org/</a><br />
Legacy versions:&nbsp;<a href="https://sourceforge.net/projects/sqlite-dotnet2/">https://sourceforge.net/projects/sqlite-dotnet2/</a><br />
<br />
The current development version can be downloaded from <a href="https://system.data.sqlite.org/index.html/timeline?y=ci">
https://system.data.sqlite.org/index.html/timeline?y=ci</a>
204
205
206
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
designed for robustness and maximum backward compatibility with previously
released versions of System.Data.SQLite.
</p>

<h2><b>Version History</b></h2>

<p>
    <b>1.0.113.0 - February XX, 2020 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_31_1.html">SQLite 3.31.1</a>.</li>
    <li>Include the &quot;LINQ&quot; partial classes in the primary managed assembly for .NET Standard 2.1. Fix for [ad28d8e026].</li>
    <li>Add SQLite_ForceLogLifecycle environment variable to force logging of calls into key members pertaining to the lifecycle of connections and their associated classes (e.g. LINQ, EF6, etc).</li>

</ul>
<p>
    <b>1.0.112.0 - October 28, 2019</b>
</p>
<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_30_1.html">SQLite 3.30.1</a>.</li>
    <li>Add preliminary support for .NET Core 3.0 and the .NET Standard 2.1. Pursuant to [ce75d320d0].</li>







|





>







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
designed for robustness and maximum backward compatibility with previously
released versions of System.Data.SQLite.
</p>

<h2><b>Version History</b></h2>

<p>
    <b>1.0.113.0 - March XX, 2020 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_31_1.html">SQLite 3.31.1</a>.</li>
    <li>Include the &quot;LINQ&quot; partial classes in the primary managed assembly for .NET Standard 2.1. Fix for [ad28d8e026].</li>
    <li>Add SQLite_ForceLogLifecycle environment variable to force logging of calls into key members pertaining to the lifecycle of connections and their associated classes (e.g. LINQ, EF6, etc).</li>
    <li>When using the (unsupported) legacy CryptoAPI based codec, skip encrypting page #1 because that can lead to database corruption and other malfunctions.</li>
</ul>
<p>
    <b>1.0.112.0 - October 28, 2019</b>
</p>
<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_30_1.html">SQLite 3.30.1</a>.</li>
    <li>Add preliminary support for .NET Core 3.0 and the .NET Standard 2.1. Pursuant to [ce75d320d0].</li>
Changes to www/news.wiki.
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
    Access to archived release packages will be granted on a case-by-case basis.
  </li>
</ul>

<div align="center"><h2><b>Version History</b></h2></div>

<p>
    <b>1.0.113.0 - February XX, 2020 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_31_1.html|SQLite 3.31.1].</li>
    <li>Include the &quot;LINQ&quot; partial classes in the primary managed assembly for .NET Standard 2.1. Fix for [ad28d8e026].</li>
    <li>Add SQLite_ForceLogLifecycle environment variable to force logging of calls into key members pertaining to the lifecycle of connections and their associated classes (e.g. LINQ, EF6, etc).</li>

</ul>
<p>
    <b>1.0.112.0 - October 28, 2019</b>
</p>
<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_30_1.html|SQLite 3.30.1].</li>
    <li>Add preliminary support for .NET Core 3.0 and the .NET Standard 2.1. Pursuant to [ce75d320d0].</li>







|





>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    Access to archived release packages will be granted on a case-by-case basis.
  </li>
</ul>

<div align="center"><h2><b>Version History</b></h2></div>

<p>
    <b>1.0.113.0 - March XX, 2020 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_31_1.html|SQLite 3.31.1].</li>
    <li>Include the &quot;LINQ&quot; partial classes in the primary managed assembly for .NET Standard 2.1. Fix for [ad28d8e026].</li>
    <li>Add SQLite_ForceLogLifecycle environment variable to force logging of calls into key members pertaining to the lifecycle of connections and their associated classes (e.g. LINQ, EF6, etc).</li>
    <li>When using the (unsupported) legacy CryptoAPI based codec, skip encrypting page #1 because that can lead to database corruption and other malfunctions.</li>
</ul>
<p>
    <b>1.0.112.0 - October 28, 2019</b>
</p>
<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_30_1.html|SQLite 3.30.1].</li>
    <li>Add preliminary support for .NET Core 3.0 and the .NET Standard 2.1. Pursuant to [ce75d320d0].</li>