Message-ID: From: "jarvis24young (@jarvis24young)" To: "postgresql-interfaces/psqlodbc" Date: Thu, 23 Apr 2026 09:07:37 +0000 Subject: [postgresql-interfaces/psqlodbc] PR #175: Validate percent escapes before decoding connection-string values List-Id: X-GitHub-Author-Id: 48787405 X-GitHub-Author-Login: jarvis24young X-GitHub-Issue: 175 X-GitHub-Repo: postgresql-interfaces/psqlodbc X-GitHub-State: merged X-GitHub-Type: pull_request X-GitHub-Url: https://github.com/postgresql-interfaces/psqlodbc/pull/175 Content-Type: text/plain; charset=utf-8 This fixes sanitizer-detected undefined behavior in connection-string percent decoding. Root cause: - `decode()` treated every `%` in a connection-string value as the beginning of a `%xx` percent escape. - It called `conv_from_hex(&in[i])` without first checking that two following hex digits were present. - For a truncated value such as `pqopt=application_name=%`, `conv_from_hex()` reads the string terminator, computes a negative value, and left-shifts it. UBSan reports this as undefined behavior. Fix: - Decode only valid `%xx` escapes where both following characters are hex digits. - Leave malformed or truncated percent sequences unchanged, preserving compatibility while avoiding undefined behavior. Regression test: - Adds `percent-decode-test`, which exercises the public `SQLDriverConnect()` path with `pqopt=application_name=%`, `%A`, `%G1`, and `%20`. - The test requires `SQLDriverConnect()` to succeed for each case, so it verifies more than just "no crash". Verification performed under ASan/UBSan: ```bash cd ~/psqlodbc-build/test export LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/13/libasan.so ODBCSYSINI=. ODBCINSTINI=./odbcinst.ini ODBCINI=./odbc.ini \ ASAN_OPTIONS=halt_on_error=1:abort_on_error=1 \ UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 \ ./exe/percent-decode-test ``` Output: ```text truncated percent: ok one hex digit: ok non-hex escape: ok valid percent escape: ok ```