Skip to content

Commit 5f20d7f

Browse files
committed
Workaround for possible bug caused by SQL/CLI PTF
It seems db2_result was returning garbage at the end of strings; an unknown PTF seemed to be causing this. My guess is something related to Unicode conversion based on the PTFs of the time. It manifests returning more data than requested, usually around twice the buffer size. As such, just allocate twice as much and truncate. Not ideal, but we're kinda forced to do this if we want to avoid a buffer overflow. It's affected one customer, but now it has affected another, so I'm moving this into git.
1 parent f85e3ff commit 5f20d7f

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

ibm_db2.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5852,12 +5852,29 @@ PHP_FUNCTION(db2_result)
58525852
if(column_type == SQL_BIGINT) {
58535853
in_length++;
58545854
}
5855-
out_ptr = (SQLPOINTER)ecalloc(1, in_length);
5855+
/*
5856+
* CB 20210128: SQL/CLI bug caused by a PTF makes SQLGetData |
5857+
* return more data than what was provided from it - seems to
5858+
* be almost the data it would have returned /plus/ the input
5859+
* length. To compensate, we'll allocate twice as much, but
5860+
* only provide the real length. This is awful and dumb, but
5861+
* it might be necessary to prevent a buffer overflow.
5862+
*/
5863+
out_ptr = (SQLPOINTER)ecalloc(1, in_length * 2);
58565864
if ( out_ptr == NULL ) {
58575865
php_error_docref(NULL, E_WARNING, "Cannot Allocate Memory");
58585866
RETURN_FALSE;
58595867
}
5868+
memset(out_ptr, 0, in_length * 2);
58605869
rc = _php_db2_get_data(stmt_res, col_num+1, SQL_C_CHAR, out_ptr, in_length, &out_length);
5870+
if (out_length > (in_length * 2)) {
5871+
php_error_docref(NULL, E_WARNING, "SQLGetData returned more data than what was provided; possible memory corruption");
5872+
/* should abort here */
5873+
}
5874+
if (out_length > in_length) {
5875+
/* yup. let's just chop it off and hope it doesn't get too worse */
5876+
((char*)out_ptr)[in_length + 1] = '\0';
5877+
}
58615878
if ( rc == SQL_ERROR ) {
58625879
RETURN_FALSE;
58635880
}

0 commit comments

Comments
 (0)