Skip to content

fix(ODBC): defensive UTF-16 length handling in makeUTF8 for Informix#5245

Open
aleks-f wants to merge 3 commits intomainfrom
informix-odbc-string-length
Open

fix(ODBC): defensive UTF-16 length handling in makeUTF8 for Informix#5245
aleks-f wants to merge 3 commits intomainfrom
informix-odbc-string-length

Conversation

@aleks-f
Copy link
Member

@aleks-f aleks-f commented Mar 15, 2026

No description provided.

@aleks-f aleks-f requested a review from Copilot March 15, 2026 13:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds IBM Informix support to the Poco::Data::ODBC test suite and provides a Nix-based local environment to run those tests via a containerized Informix instance.

Changes:

  • Register new ODBCInformixTest in the ODBC test suite and build.
  • Add Informix-specific ODBC test implementation (schema recreation + suite wiring).
  • Add informix.nix Nix shell to provision Informix (Podman) and configure unixODBC for running the tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Data/ODBC/testsuite/src/ODBCTestSuite.cpp Adds Informix test suite registration.
Data/ODBC/testsuite/src/ODBCInformixTest.h Declares Informix ODBC test class and overrides.
Data/ODBC/testsuite/src/ODBCInformixTest.cpp Implements Informix-specific schema helpers and test suite wiring.
Data/ODBC/testsuite/Makefile Includes Informix test object in build.
Data/ODBC/informix.nix Provides Nix shell + Podman setup to run Informix ODBC tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +165 to +170
# Also copy any versioned .so files
for lib in $(podman exec "$tmp_container" sh -c 'ls /opt/ibm/informix/lib/libif*.so* /opt/ibm/informix/lib/cli/libif*.so* 2>/dev/null' 2>/dev/null); do
local basename=$(basename "$lib")
local dirname=$(dirname "$lib" | sed 's|/opt/ibm/informix/||')
podman cp "$tmp_container:$lib" "$INFORMIX_CLIENT_DIR/$dirname/" 2>/dev/null || true
done
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid — podman exec requires a running container, but this one is only podman created. The block is also redundant: lines 157-158 already podman cp the entire cli/ and esql/ directories (including versioned .so files), and lines 161-163 copy the named libraries from lib/. Removing the dead block.

Comment on lines +119 to +129
if [ ! -f "$HOME/.config/containers/policy.json" ]; then
cat > "$HOME/.config/containers/policy.json" << 'POLICYJSON'
{
"default": [
{
"type": "insecureAcceptAnything"
}
]
}
POLICYJSON
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid concern. The conditional only writes it if the file does not already exist, but it does affect all rootless Podman on the host. Could be improved by setting CONTAINERS_POLICY_JSON env var to a test-local file instead of writing to the global location.

Copy link
Contributor

@matejk matejk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Overall the test class follows the existing ODBC test patterns (DB2, MySQL, PostgreSQL) closely — Informix-specific SQL types are correct (BYTE for BLOBs, DATETIME YEAR TO FRACTION(5) for timestamps), dropObject handles the right Informix error codes (-206, -319), and the Nix shell is well-documented.

Bug

podman exec on a stopped container (informix.nix line 172):

for lib in $(podman exec "$tmp_container" sh -c 'ls /opt/ibm/informix/lib/libif*.so* …'); do

The temp container is created with podman create (not started), so podman exec will always fail and this loop never runs. The earlier podman cp calls work on stopped containers, but exec does not. Fix by either starting/stopping the temp container around this block, or replacing the exec with a podman cp-based approach to enumerate files.

Issues

  1. Comment says sysmaster, DSN says poco_test (informix.nix line 15):

    # Test database: sysmaster (user: informix, password: poco)
    

    The actual test database is poco_test (configured in the DSN on line 229, created on line 300). sysmaster is only used for health checks.

  2. Global policy.json weakens Podman security (informix.nix lines 125-135):
    Writing insecureAcceptAnything to ~/.config/containers/policy.json disables image signature verification for all rootless Podman usage on the host, not just this test. Consider scoping via CONTAINERS_POLICY_JSON env var pointing to a test-local file, or at minimum documenting the trade-off.

  3. --privileged container (informix.nix line 271):
    Running with --privileged is common for Informix due to shared memory requirements, but a brief comment explaining why it's needed would help future readers.

  4. Copyright year in new files (ODBCInformixTest.cpp, ODBCInformixTest.h):
    Both say Copyright (c) 2006 — copied from existing test files. Since these are brand-new files, the year should reflect when they were actually written (2026).

Note on Copilot review

The Copilot review flagged recreateLogTable() line 287 as a bug, claiming the %s placeholder is never formatted. That's a false positive — session() << sql, "T_POCO_LOG", now; is the standard Poco Data binding pattern, used identically in ODBCPostgreSQLTest::recreateLogTable() and ODBCMySQLTest::recreateLogTable().

@matejk
Copy link
Contributor

matejk commented Mar 16, 2026

Added: Informix makeUTF8 fix (port of aleph-us/macchina.io#99)

New commit 223151f adds the actual bug fix that makes Informix ODBC work with string columns.

Problem

Informix ODBC driver reports UTF-16 string lengths larger than the allocated wide-char buffer during column metadata retrieval (SQLColAttribute, SQLDescribeCol). The existing makeUTF8() threw InvalidArgumentException("Specified length exceeds available length."), making any query with string columns fail.

Fix

Replaced strict validation with defensive clamping in both platform paths:

  • Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.hmakeUTF8(): handle non-positive lengths (zero target buffer), clamp oversized lengths to buffer size, align to wchar_t boundary
  • Data/ODBC/src/Unicode_UNIXODBC.cpp — same clamping logic, using SQLWCHAR instead of wchar_t

The fix is safe for other drivers — clamp conditions are only triggered when the driver over-reports lengths, which well-behaved drivers don't do. Tested on both MS SQL and Informix in macchina.io.

Other fixes in this commit

  • Data/ODBC/informix.nix: fixed comment (sysmasterpoco_test — the actual test database)
  • Data/ODBC/testsuite/src/ODBCInformixTest.{cpp,h}: copyright year 20062006-2026

aleks-f and others added 2 commits March 17, 2026 15:45
Informix ODBC driver may report string lengths larger than the
allocated wide-char buffer during metadata retrieval (e.g.
SQLColAttribute, SQLDescribeCol), causing makeUTF8 to throw
"Specified length exceeds available length". Replace strict
validation with defensive clamping: handle non-positive lengths,
clamp to buffer size, and align to wchar_t/SQLWCHAR boundary.

Port of aleph-us/macchina.io#99 / PR #100. Safe for other drivers
as clamp conditions are never triggered with correct length reporting.

Also fix informix.nix comment (sysmaster -> poco_test) and copyright
years in ODBCInformixTest files.
@matejk matejk force-pushed the informix-odbc-string-length branch from 223151f to 4509cf0 Compare March 17, 2026 14:45
@matejk matejk changed the title feat(ODBC): add informix.nix and tests aleph-us/macchina.io#99 fix(ODBC): defensive UTF-16 length handling in makeUTF8 for Informix Mar 19, 2026
@matejk matejk added this to the Release 1.15.1 milestone Mar 19, 2026
@matejk
Copy link
Contributor

matejk commented Mar 19, 2026

@aleks-f , @pavledragisic: The docker image installed in informix.nix with padman does not contain Informix ODBC drivers. I tried with other docker images with no luck.

Where did you get the drivers to test with?

@matejk matejk added the bug label Mar 20, 2026
The Informix Developer Edition container does not include the Client SDK
(CSDK/ODBC driver). Remove the non-functional extraction function and
related code. Add a runtime check that warns if the driver is not
registered with unixODBC, with a link to the IBM download page.

Also document the --privileged flag requirement for Informix shared
memory setup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants