Skip to content

Commit 441d211

Browse files
committed
Add sqlite3_snprintf / sqlite3_mprintf to compat shim
Second gdb backtrace showed pdo_sqlite calling sqlite3_snprintf, which Turso doesn't export. The fall-through to system libsqlite3 used that library's own allocator internals, which don't work on a Turso-allocated handle, so pdo_sqlite deref'd NULL from a failed malloc. Provide libc- based implementations so pdo_sqlite stays inside our stack end to end.
1 parent 9eb972b commit 441d211

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

.github/workflows/phpunit-tests-turso.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ jobs:
127127
id: shim
128128
run: |
129129
cat > /tmp/turso-compat-shim.c <<'C'
130+
#include <stdio.h>
131+
#include <stdarg.h>
132+
#include <stdlib.h>
133+
#include <string.h>
134+
130135
typedef struct sqlite3 sqlite3;
131136
typedef struct sqlite3_stmt sqlite3_stmt;
132137
typedef struct sqlite3_value sqlite3_value;
@@ -175,6 +180,46 @@ jobs:
175180
176181
extern void sqlite3_result_int64(sqlite3_context *ctx, long long v);
177182
void sqlite3_result_int(sqlite3_context *ctx, int v) { sqlite3_result_int64(ctx, (long long)v); }
183+
184+
// SQLite's own formatting API. Turso doesn't export it, so without a
185+
// shim pdo_sqlite falls through to system libsqlite3, where these
186+
// functions interact badly with Turso's malloc/free and crash.
187+
// This implementation is libc-based and ignores SQLite's %q / %Q
188+
// format specifiers (used for SQL-quoting); pdo_sqlite uses the
189+
// plain %s family for error message formatting, which is handled.
190+
char *sqlite3_vsnprintf(int n, char *dst, const char *fmt, va_list ap) {
191+
if (!dst || n <= 0) return dst;
192+
vsnprintf(dst, (size_t)n, fmt, ap);
193+
return dst;
194+
}
195+
196+
char *sqlite3_snprintf(int n, char *dst, const char *fmt, ...) {
197+
va_list ap;
198+
va_start(ap, fmt);
199+
sqlite3_vsnprintf(n, dst, fmt, ap);
200+
va_end(ap);
201+
return dst;
202+
}
203+
204+
char *sqlite3_vmprintf(const char *fmt, va_list ap) {
205+
va_list ap2;
206+
va_copy(ap2, ap);
207+
int len = vsnprintf(NULL, 0, fmt, ap2);
208+
va_end(ap2);
209+
if (len < 0) return NULL;
210+
char *buf = (char *)malloc((size_t)len + 1);
211+
if (!buf) return NULL;
212+
vsnprintf(buf, (size_t)len + 1, fmt, ap);
213+
return buf;
214+
}
215+
216+
char *sqlite3_mprintf(const char *fmt, ...) {
217+
va_list ap;
218+
va_start(ap, fmt);
219+
char *s = sqlite3_vmprintf(fmt, ap);
220+
va_end(ap);
221+
return s;
222+
}
178223
C
179224
180225
SHIM=/tmp/libturso-compat-shim.so

0 commit comments

Comments
 (0)