Skip to content

Commit 872fb00

Browse files
committed
major rework of mutex allocation and management
1 parent 4663c5a commit 872fb00

5 files changed

Lines changed: 142 additions & 163 deletions

File tree

src/crypto_impl.c

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,15 @@ static volatile int mem_security_initialized = 0;
5656
static volatile int mem_security_activated = 0;
5757
static volatile unsigned int sqlcipher_activate_count = 0;
5858
static volatile sqlite3_mem_methods default_mem_methods;
59-
static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
6059
static sqlcipher_provider *default_provider = NULL;
6160

61+
static sqlite3_mutex* sqlcipher_static_mutex[SQLCIPHER_MUTEX_COUNT];
62+
63+
sqlite3_mutex* sqlcipher_mutex(int mutex) {
64+
if(mutex < 0 || mutex >= SQLCIPHER_MUTEX_COUNT) return NULL;
65+
return sqlcipher_static_mutex[mutex];
66+
}
67+
6268
static int sqlcipher_mem_init(void *pAppData) {
6369
return default_mem_methods.xInit(pAppData);
6470
}
@@ -116,9 +122,9 @@ void sqlcipher_init_memmethods() {
116122
}
117123

118124
int sqlcipher_register_provider(sqlcipher_provider *p) {
119-
CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
120-
sqlite3_mutex_enter(sqlcipher_provider_mutex);
121-
CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
125+
CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering SQLCIPHER_MUTEX_PROVIDER\n");
126+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
127+
CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered SQLCIPHER_MUTEX_PROVIDER"\n);
122128

123129
if(default_provider != NULL && default_provider != p) {
124130
/* only free the current registerd provider if it has been initialized
@@ -127,9 +133,9 @@ int sqlcipher_register_provider(sqlcipher_provider *p) {
127133
sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
128134
}
129135
default_provider = p;
130-
CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
131-
sqlite3_mutex_leave(sqlcipher_provider_mutex);
132-
CODEC_TRACE_MUTEX("sqlcipher_register_provider: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
136+
CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving SQLCIPHER_MUTEX_PROVIDER\n");
137+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
138+
CODEC_TRACE_MUTEX("sqlcipher_register_provider: left SQLCIPHER_MUTEX_PROVIDER\n");
133139

134140
return SQLITE_OK;
135141
}
@@ -146,11 +152,12 @@ void sqlcipher_activate() {
146152
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
147153
CODEC_TRACE_MUTEX("sqlcipher_activate: entered static master mutex\n");
148154

149-
if(sqlcipher_provider_mutex == NULL) {
150-
/* allocate a new mutex to guard access to the provider */
151-
CODEC_TRACE_MUTEX("sqlcipher_activate: allocating sqlcipher provider mutex\n");
152-
sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
153-
CODEC_TRACE_MUTEX("sqlcipher_activate: allocated sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
155+
/* allocate new mutexes */
156+
if(sqlcipher_activate_count == 0) {
157+
int i;
158+
for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) {
159+
sqlcipher_static_mutex[i] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
160+
}
154161
}
155162

156163
/* check to see if there is a provider registered at this point
@@ -196,30 +203,32 @@ void sqlcipher_deactivate() {
196203
sqlcipher_activate_count--;
197204
/* if no connections are using sqlcipher, cleanup globals */
198205
if(sqlcipher_activate_count < 1) {
199-
CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
200-
sqlite3_mutex_enter(sqlcipher_provider_mutex);
201-
CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
206+
207+
CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering SQLCIPHER_MUTEX_PROVIDER\n");
208+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
209+
CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered SQLCIPHER_MUTEX_PROVIDER\n");
202210

203211
if(default_provider != NULL) {
204212
sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
205213
default_provider = NULL;
206214
}
207215

208-
CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
209-
sqlite3_mutex_leave(sqlcipher_provider_mutex);
210-
CODEC_TRACE_MUTEX("sqlcipher_deactivate: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
211-
212-
/* last connection closed, free provider mutex*/
213-
CODEC_TRACE_MUTEX("sqlcipher_deactivate: freeing sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
214-
sqlite3_mutex_free(sqlcipher_provider_mutex);
215-
CODEC_TRACE_MUTEX("sqlcipher_deactivate: freed sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
216-
217-
sqlcipher_provider_mutex = NULL;
216+
CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER\n");
217+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
218+
CODEC_TRACE_MUTEX("sqlcipher_deactivate: left SQLCIPHER_MUTEX_PROVIDER\n");
218219

219-
sqlcipher_activate_count = 0; /* reset activation count */
220220
#ifdef SQLCIPHER_EXT
221221
sqlcipher_ext_provider_destroy();
222222
#endif
223+
224+
/* last connection closed, free mutexes */
225+
if(sqlcipher_activate_count == 0) {
226+
int i;
227+
for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) {
228+
sqlite3_mutex_free(sqlcipher_static_mutex[i]);
229+
}
230+
}
231+
sqlcipher_activate_count = 0; /* reset activation count */
223232
}
224233

225234
CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving static master mutex\n");
@@ -845,15 +854,15 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, const voi
845854
if(ctx->provider == NULL) return SQLITE_NOMEM;
846855

847856
/* make a copy of the provider to be used for the duration of the context */
848-
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
849-
sqlite3_mutex_enter(sqlcipher_provider_mutex);
850-
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
857+
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entering SQLCIPHER_MUTEX_PROVIDER\n");
858+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
859+
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entered SQLCIPHER_MUTEX_PROVIDER\n");
851860

852861
memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider));
853862

854-
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
855-
sqlite3_mutex_leave(sqlcipher_provider_mutex);
856-
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
863+
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: leaving SQLCIPHER_MUTEX_PROVIDER\n");
864+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
865+
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: left SQLCIPHER_MUTEX_PROVIDER\n");
857866

858867
CODEC_TRACE("sqlcipher_codec_ctx_init: calling provider ctx_init\n");
859868
if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc;

src/crypto_libtomcrypt.c

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
static prng_state prng;
4040
static volatile unsigned int ltc_init = 0;
4141
static volatile unsigned int ltc_ref_count = 0;
42-
static sqlite3_mutex* ltc_rand_mutex = NULL;
4342

4443
#define LTC_CIPHER "rijndael"
4544

@@ -48,34 +47,37 @@ static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
4847
int data_to_read = length;
4948
int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
5049
const unsigned char * data = (const unsigned char *)buffer;
51-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
52-
sqlite3_mutex_enter(ltc_rand_mutex);
53-
#endif
54-
while(data_to_read > 0){
55-
rc = fortuna_add_entropy(data, block_sz, &prng);
56-
rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK;
57-
if(rc != SQLITE_OK){
58-
break;
59-
}
60-
data_to_read -= block_sz;
61-
data += block_sz;
62-
block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
50+
51+
CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
52+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
53+
CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
54+
55+
while(data_to_read > 0){
56+
rc = fortuna_add_entropy(data, block_sz, &prng);
57+
rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK;
58+
if(rc != SQLITE_OK){
59+
break;
6360
}
64-
fortuna_ready(&prng);
65-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
66-
sqlite3_mutex_leave(ltc_rand_mutex);
67-
#endif
61+
data_to_read -= block_sz;
62+
data += block_sz;
63+
block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
64+
}
65+
fortuna_ready(&prng);
66+
67+
CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
68+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
69+
CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
70+
6871
return rc;
6972
}
7073

7174
static int sqlcipher_ltc_activate(void *ctx) {
7275
unsigned char random_buffer[FORTUNA_MAX_SZ];
73-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
74-
if(ltc_rand_mutex == NULL){
75-
ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
76-
}
77-
sqlite3_mutex_enter(ltc_rand_mutex);
78-
#endif
76+
77+
CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
78+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
79+
CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
80+
7981
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
8082
if(ltc_init == 0) {
8183
if(register_prng(&fortuna_desc) < 0) return SQLITE_ERROR;
@@ -86,41 +88,42 @@ static int sqlcipher_ltc_activate(void *ctx) {
8688
if(fortuna_start(&prng) != CRYPT_OK) {
8789
return SQLITE_ERROR;
8890
}
91+
8992
ltc_init = 1;
9093
}
9194
ltc_ref_count++;
95+
9296
#ifndef SQLCIPHER_TEST
9397
sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
9498
#endif
95-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
96-
sqlite3_mutex_leave(ltc_rand_mutex);
97-
#endif
99+
98100
if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
99101
return SQLITE_ERROR;
100102
}
101103
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
104+
105+
CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
106+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
107+
CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
108+
102109
return SQLITE_OK;
103110
}
104111

105112
static int sqlcipher_ltc_deactivate(void *ctx) {
106-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
107-
sqlite3_mutex_enter(ltc_rand_mutex);
108-
#endif
113+
CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
114+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
115+
CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
116+
109117
ltc_ref_count--;
110118
if(ltc_ref_count == 0){
111119
fortuna_done(&prng);
112120
sqlcipher_memset((void *)&prng, 0, sizeof(prng));
113-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
114-
sqlite3_mutex_leave(ltc_rand_mutex);
115-
sqlite3_mutex_free(ltc_rand_mutex);
116-
ltc_rand_mutex = NULL;
117-
#endif
118-
}
119-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
120-
else {
121-
sqlite3_mutex_leave(ltc_rand_mutex);
122121
}
123-
#endif
122+
123+
CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
124+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
125+
CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
126+
124127
return SQLITE_OK;
125128
}
126129

@@ -133,13 +136,16 @@ static const char* sqlcipher_ltc_get_provider_version(void *ctx) {
133136
}
134137

135138
static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) {
136-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
137-
sqlite3_mutex_enter(ltc_rand_mutex);
138-
#endif
139+
CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
140+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
141+
CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
142+
139143
fortuna_read(buffer, length, &prng);
140-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
141-
sqlite3_mutex_leave(ltc_rand_mutex);
142-
#endif
144+
145+
CODEC_TRACE_MUTEX("sqlcipher_ltc_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
146+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
147+
CODEC_TRACE_MUTEX("sqlcipher_ltc_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
148+
143149
return SQLITE_OK;
144150
}
145151

src/crypto_nss.c

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,55 +39,40 @@
3939

4040
static NSSInitContext* nss_init_context = NULL;
4141
static unsigned int nss_init_count = 0;
42-
static sqlite3_mutex* nss_mutex = NULL;
4342

4443
int sqlcipher_nss_setup(sqlcipher_provider *p);
4544

4645
static int sqlcipher_nss_activate(void *ctx) {
47-
if(nss_mutex == NULL){
48-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: allocating nss_mutex");
49-
nss_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
50-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: allocated nss_mutex %p", nss_mutex);
51-
}
5246

53-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering nss_mutex %p\n", nss_mutex);
54-
sqlite3_mutex_enter(nss_mutex);
55-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex);
47+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
48+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
49+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
5650
if (nss_init_context == NULL) {
5751
nss_init_context = NSS_InitContext("", "", "", "", NULL,
5852
NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB |
5953
NSS_INIT_FORCEOPEN | NSS_INIT_OPTIMIZESPACE | NSS_INIT_NOROOTINIT);
6054
}
6155
nss_init_count++;
62-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex);
63-
sqlite3_mutex_leave(nss_mutex);
64-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex);
56+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
57+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
58+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
6559
return SQLITE_OK;
6660
}
6761

6862
static int sqlcipher_nss_deactivate(void *ctx) {
69-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering nss_mutex %p\n", nss_mutex);
70-
sqlite3_mutex_enter(nss_mutex);
71-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex);
63+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
64+
sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
65+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
7266

7367
nss_init_count--;
7468
if (nss_init_count == 0 && nss_init_context != NULL) {
75-
sqlite3_mutex *temp_mutex;
7669
NSS_ShutdownContext(nss_init_context);
7770
nss_init_context = NULL;
78-
temp_mutex = nss_mutex;
79-
nss_mutex = NULL;
80-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex);
81-
sqlite3_mutex_leave(temp_mutex);
82-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex);
83-
CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: freeing nss_mutex %p", nss_mutex);
84-
sqlite3_mutex_free(temp_mutex);
85-
CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: freed nss_mutex %p", nss_mutex);
86-
} else {
87-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex);
88-
sqlite3_mutex_leave(nss_mutex);
89-
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex);
90-
}
71+
}
72+
73+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
74+
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
75+
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
9176
return SQLITE_OK;
9277
}
9378

0 commit comments

Comments
 (0)