Package: libsqliteodbc
Version: 0.99991-3
Severity: important
Tags: upstream patch
X-Debbugs-Cc: [email protected]

Programs that use SQLGetTypeInfo (notable example is pyodbc) are
crashing now. This happened after Fix-incompatible-pointer patch was
added. This is caused by incorrect free function that is used -
drvgettypeinfo returns result that is stored in static buffers but
rowfree function tries to deallocate it.

I suspect that SQLTables (drvtables) has same issue but don't have any
code that uses this function.

Minimal program to reproduce this error:

```
#include <stdio.h>
#include <string.h>
#include <sql.h>
#include <sqlext.h>

int fail(const char *err)
{
        printf("%s\n", err);
        return -1;
}

int main()
{
        const char * settings = "driver=SQLite3;database=/tmp/file.db";

        SQLHENV env = NULL;
        if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, 
&env)))
                return fail("Failed to allocate ODBC Environment");

        if (!SQL_SUCCEEDED(SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, 
(SQLPOINTER) SQL_OV_ODBC3, 0)))
                return fail("Failed to request ODBCv3");

        SQLHDBC dbc = NULL;
        if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc)))
                return fail("Failed to allocate ODBC Connection");

        char buf[SQL_MAX_OPTION_STRING_LENGTH];
        SQLSMALLINT buflen = sizeof(buf);
        if (!SQL_SUCCEEDED(SQLDriverConnect(dbc, NULL, (SQLCHAR *)settings, 
strlen(settings), (SQLCHAR *)buf, sizeof(buf), &buflen, SQL_DRIVER_NOPROMPT)))
                return fail("Failed to connect");
        printf("Connection string: %s\n", buf);

        HSTMT hstmt;
        if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, dbc, &hstmt)))
                return -1;

        /*
        // Code from pyodbc
        SQLINTEGER columnsize;
        if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_VARCHAR)) && 
SQL_SUCCEEDED(SQLFetch(hstmt)) &&
            SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, 
sizeof(columnsize), 0))) {
                printf("Column size: %d\n", columnsize);
        }
        SQLFreeStmt(hstmt, SQL_CLOSE);
        */

        // Minimal variant
        SQLGetTypeInfo(hstmt, SQL_VARCHAR);
        SQLFreeHandle(SQL_HANDLE_STMT, hstmt);

        SQLDisconnect(dbc);  
        SQLFreeHandle(SQL_HANDLE_DBC, dbc);
        SQLFreeHandle(SQL_HANDLE_ENV, env);
}
```

Inline patch:

```
diff --git a/debian/patches/Fix-incompatible-pointer-compilation-error.patch 
b/debian/patches/Fix-incompatible-pointer-compilation-error.patch
index 3494c8a..b83831d 100644
--- a/debian/patches/Fix-incompatible-pointer-compilation-error.patch
+++ b/debian/patches/Fix-incompatible-pointer-compilation-error.patch
@@ -44,7 +44,7 @@ index 5f5959d..9b001ad 100644
      s->rowfree = xfree__;
  #else
 -    s->rowfree = sqlite3_free;
-+    s->rowfree = sqlite3_free_table;
++    s->rowfree = (void (*)(char **)) sqlite3_free;
  #endif
      memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
      if (sqltype == SQL_ALL_TYPES) {
@@ -92,7 +92,7 @@ index 055dba2..ad30b4a 100644
      s->rowfree = xfree__;
  #else
 -    s->rowfree = free;
-+    s->rowfree = freerows;
++    s->rowfree = (void (*)(char **)) free;
  #endif
      memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
      if (sqltype == SQL_ALL_TYPES) {
```

-- System Information:
Debian Release: 13.1
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.1.0-9-amd64 (SMP w/4 CPU threads; PREEMPT)
Locale: LANG=C, LC_CTYPE=C (charmap=UTF-8) (ignored: LC_ALL set to 
en_US.UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: unable to detect

Versions of packages libsqliteodbc depends on:
ii  libc6         2.41-12
ii  libsqlite3-0  3.46.1-7
ii  odbcinst      2.3.12-2

libsqliteodbc recommends no packages.

libsqliteodbc suggests no packages.

-- no debconf information
diff --git a/debian/patches/Fix-incompatible-pointer-compilation-error.patch 
b/debian/patches/Fix-incompatible-pointer-compilation-error.patch
index 3494c8a..b83831d 100644
--- a/debian/patches/Fix-incompatible-pointer-compilation-error.patch
+++ b/debian/patches/Fix-incompatible-pointer-compilation-error.patch
@@ -44,7 +44,7 @@ index 5f5959d..9b001ad 100644
      s->rowfree = xfree__;
  #else
 -    s->rowfree = sqlite3_free;
-+    s->rowfree = sqlite3_free_table;
++    s->rowfree = (void (*)(char **)) sqlite3_free;
  #endif
      memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
      if (sqltype == SQL_ALL_TYPES) {
@@ -92,7 +92,7 @@ index 055dba2..ad30b4a 100644
      s->rowfree = xfree__;
  #else
 -    s->rowfree = free;
-+    s->rowfree = freerows;
++    s->rowfree = (void (*)(char **)) free;
  #endif
      memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
      if (sqltype == SQL_ALL_TYPES) {
diff --git a/debian/patches/Fix-incompatible-pointer-compilation-error.patch 
b/debian/patches/Fix-incompatible-pointer-compilation-error.patch
index 3494c8a..b83831d 100644
--- a/debian/patches/Fix-incompatible-pointer-compilation-error.patch
+++ b/debian/patches/Fix-incompatible-pointer-compilation-error.patch
@@ -44,7 +44,7 @@ index 5f5959d..9b001ad 100644
      s->rowfree = xfree__;
  #else
 -    s->rowfree = sqlite3_free;
-+    s->rowfree = sqlite3_free_table;
++    s->rowfree = (void (*)(char **)) sqlite3_free;
  #endif
      memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
      if (sqltype == SQL_ALL_TYPES) {
@@ -92,7 +92,7 @@ index 055dba2..ad30b4a 100644
      s->rowfree = xfree__;
  #else
 -    s->rowfree = free;
-+    s->rowfree = freerows;
++    s->rowfree = (void (*)(char **)) free;
  #endif
      memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
      if (sqltype == SQL_ALL_TYPES) {

Reply via email to