]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-8.0'
authorChristoph M. Becker <cmbecker69@gmx.de>
Thu, 18 Mar 2021 14:31:23 +0000 (15:31 +0100)
committerChristoph M. Becker <cmbecker69@gmx.de>
Thu, 18 Mar 2021 14:31:23 +0000 (15:31 +0100)
* PHP-8.0:
  Fix #80783: PDO ODBC truncates BLOB records at every 256th byte

1  2 
ext/pdo_odbc/odbc_stmt.c

index a80aab9a8873a471f771a0a5bb76c57c9b84a940,5e882fbcc9a0291e247dd381d9aae5d05afc4b87..c1f4b5f497e9eb478c82ef2fd9ff499dfd045afe
@@@ -639,6 -649,10 +639,7 @@@ static int odbc_stmt_get_col(pdo_stmt_
  
        /* if it is a column containing "long" data, perform late binding now */
        if (C->is_long) {
 -              zend_ulong used = 0;
 -              char *buf;
+               SQLLEN orig_fetched_len = SQL_NULL_DATA;
                RETCODE rc;
  
                /* fetch it into C->data, which is allocated with a length
                         this loop has to work whether or not SQLGetData() provides the total column length.
                         calling SQLDescribeCol() or other, specifically to get the column length, then doing a single read
                         for that size would be slower except maybe for extremely long columns.*/
 -                      char *buf2;
 -
 -                      buf2 = emalloc(256);
 -                      buf = estrndup(C->data, 256);
 -                      used = 255; /* not 256; the driver NUL terminated the buffer */
 +                      char *buf2 = emalloc(256);
-                       zend_string *str = zend_string_init(C->data, 255, 0);
++                      zend_string *str = zend_string_init(C->data, 256, 0);
 +                      size_t used = 255; /* not 256; the driver NUL terminated the buffer */
  
                        do {
                                C->fetched_len = 0;
                                        /* point 5, in section "Retrieving Data with SQLGetData" in http://msdn.microsoft.com/en-us/library/windows/desktop/ms715441(v=vs.85).aspx
                                         states that if SQL_SUCCESS_WITH_INFO, fetched_len will be > 255 (greater than buf2's size)
                                         (if a driver fails to follow that and wrote less than 255 bytes to buf2, this will AV or read garbage into buf) */
-                                       str = zend_string_realloc(str, used + 255, 0);
-                                       memcpy(ZSTR_VAL(str) + used, buf2, 255);
 -                                      buf = erealloc(buf, used + 255+1);
 -                                      memcpy(buf + used, buf2, 255);
++                                      str = zend_string_realloc(str, used + 256, 0);
++                                      memcpy(ZSTR_VAL(str) + used, buf2, 256);
                                        used = used + 255;
                                } else if (rc==SQL_SUCCESS) {
 -                                      buf = erealloc(buf, used + C->fetched_len+1);
 -                                      memcpy(buf + used, buf2, C->fetched_len);
 +                                      str = zend_string_realloc(str, used + C->fetched_len, 0);
 +                                      memcpy(ZSTR_VAL(str) + used, buf2, C->fetched_len);
                                        used = used + C->fetched_len;
                                } else {
                                        /* includes SQL_NO_DATA */