Type:
Bug
Priority:
Major
Resolution:
Fixed
Affects Version/s:
2.2.3
Component/s:
None
mysql_stmt_fetch_column always copy field data with offset 0.
Code to repeat the bug (extended for blob field test_fetch_offset test from fetch.c suite)
static int test_fetch_offset(MYSQL *mysql)
{
MYSQL_STMT *stmt;
MYSQL_BIND my_bind[2];
char data[11], chunk[5];
ulong length[2];
int rc;
my_bool is_null[2];
char *query = "SELECT * FROM t1";
rc= mysql_query(mysql, "drop table if exists t1");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "create table t1(a char(10), b mediumblob)");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "insert into t1 values('abcdefghij', 'klmnopqrstzy'), (null, null)");
check_mysql_rc(rc, mysql);
stmt= mysql_stmt_init(mysql);
FAIL_IF(!stmt, mysql_error(mysql));
rc= mysql_stmt_prepare(stmt, query, (unsigned long)strlen(query));
check_stmt_rc(rc,stmt);
memset(my_bind, '\0', sizeof(my_bind));
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
my_bind[0].buffer= (void *)data;
my_bind[0].buffer_length= 11;
my_bind[0].is_null= &is_null[0];
my_bind[0].length= &length[0];
my_bind[1].buffer_type= MYSQL_TYPE_STRING;
my_bind[1].buffer= NULL;
my_bind[1].buffer_length= 0;
my_bind[1].is_null= &is_null[1];
my_bind[1].length= &length[1];
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc,stmt);
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
FAIL_IF(!rc, "Error expected");
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc,stmt);
rc= mysql_stmt_bind_result(stmt, my_bind);
check_stmt_rc(rc,stmt);
rc= mysql_stmt_store_result(stmt);
check_stmt_rc(rc,stmt);
rc= mysql_stmt_fetch(stmt);
FAIL_UNLESS(rc == MYSQL_DATA_TRUNCATED, "rc != MYSQL_DATA_TRUNCATED");
data[0]= '\0';
rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 0);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(data, "abcd", 4) == 0 && length[0] == 10), "Wrong value");
rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 5);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(data, "fg", 2) == 0 && length[0] == 10), "Wrong value");
rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 9);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(data, "j", 1) == 0 && length[0] == 10), "Wrong value");
/* Now blob field */
my_bind[1].buffer= chunk;
my_bind[1].buffer_length= sizeof(chunk);
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 0);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(chunk, "klmno", 5) == 0 && length[1] == 12), "Wrong value");
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 5);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(chunk, "pqrst", 5) == 0 && length[1] == 12), "Wrong value");
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 10);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(chunk, "zy", 2) == 0 && length[1] == 12), "Wrong value");
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt);
memset(is_null, 0, sizeof(is_null));
rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 0);
check_stmt_rc(rc,stmt);
FAIL_IF(is_null[0] != 1, "Null flag not set");
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 0);
check_stmt_rc(rc,stmt);
FAIL_IF(is_null[1] != 1, "Null flag not set");
rc= mysql_stmt_fetch(stmt);
FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
FAIL_IF(!rc, "Error expected");
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table t1");
check_mysql_rc(rc, mysql);
return OK;
}
Proposed fix:
diff --git a/libmariadb/my_stmt_codec.c b/libmariadb/my_stmt_codec.c
index 7d90151..6e9dee2 100644
--- a/libmariadb/my_stmt_codec.c
+++ b/libmariadb/my_stmt_codec.c
@@ -925,8 +925,9 @@ void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
if (!(field->flags & BINARY_FLAG) && r_param->buffer_type == MYSQL_TYPE_STRING)
field_length++;
- copylen= MIN(field_length, r_param->buffer_length);
- memcpy(r_param->buffer, *row, copylen);
+ /* Making sure that we do not copy past the field. e.g. if offset >= field_length, copylen is 0 */
+ copylen= MIN(field_length - MIN(r_param->offset, field_length), r_param->buffer_length);
+ memcpy(r_param->buffer, *row + MIN(r_param->offset, field_length), copylen);
*r_param->error= copylen < field_length;
/* don't count trailing zero if we fetch into string */
@@ -934,9 +935,9 @@ void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
!*r_param->error)
field_length--;
- *r_param->length= field_length;
+ *r_param->length= field_length; /*copylen;*/
- (*row) += field_length;
+ (*row) += copylen/*field_length*/;
}
/* }}} */
{"report":{"fcp":789.4000000953674,"ttfb":163.60000014305115,"pageVisibility":"visible","entityId":57487,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":1,"journeyId":"c10d49b0-cf45-47f1-8112-8353bf91564e","navigationType":0,"readyForUser":878.9000000953674,"redirectCount":0,"resourceLoadedEnd":936.2000000476837,"resourceLoadedStart":170.20000004768372,"resourceTiming":[{"duration":139.90000009536743,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2bu7/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":170.20000004768372,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":170.20000004768372,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":310.10000014305115,"responseStart":0,"secureConnectionStart":0},{"duration":139.70000004768372,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2bu7/820016/12ta74/8679b4946efa1a0bb029a3a22206fb5d/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":170.5,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":170.5,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":310.2000000476837,"responseStart":0,"secureConnectionStart":0},{"duration":148.90000009536743,"initiatorType":"script","name":"https://jira.mariadb.org/s/fbf975c0cce4b1abf04784eeae9ba1f4-CDN/lu2bu7/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":170.5,"connectEnd":170.5,"connectStart":170.5,"domainLookupEnd":170.5,"domainLookupStart":170.5,"fetchStart":170.5,"redirectEnd":0,"redirectStart":0,"requestStart":170.5,"responseEnd":319.40000009536743,"responseStart":319.2999999523163,"secureConnectionStart":170.5},{"duration":185.29999995231628,"initiatorType":"script","name":"https://jira.mariadb.org/s/099b33461394b8015fc36c0a4b96e19f-CDN/lu2bu7/820016/12ta74/8679b4946efa1a0bb029a3a22206fb5d/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true","startTime":170.60000014305115,"connectEnd":170.60000014305115,"connectStart":170.60000014305115,"domainLookupEnd":170.60000014305115,"domainLookupStart":170.60000014305115,"fetchStart":170.60000014305115,"redirectEnd":0,"redirectStart":0,"requestStart":170.60000014305115,"responseEnd":355.90000009536743,"responseStart":355.90000009536743,"secureConnectionStart":170.60000014305115},{"duration":189.20000004768372,"initiatorType":"script","name":"https://jira.mariadb.org/s/94c15bff32baef80f4096a08aceae8bc-CDN/lu2bu7/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":170.70000004768372,"connectEnd":170.70000004768372,"connectStart":170.70000004768372,"domainLookupEnd":170.70000004768372,"domainLookupStart":170.70000004768372,"fetchStart":170.70000004768372,"redirectEnd":0,"redirectStart":0,"requestStart":170.70000004768372,"responseEnd":359.90000009536743,"responseStart":359.90000009536743,"secureConnectionStart":170.70000004768372},{"duration":192.40000009536743,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":170.79999995231628,"connectEnd":170.79999995231628,"connectStart":170.79999995231628,"domainLookupEnd":170.79999995231628,"domainLookupStart":170.79999995231628,"fetchStart":170.79999995231628,"redirectEnd":0,"redirectStart":0,"requestStart":170.79999995231628,"responseEnd":363.2000000476837,"responseStart":363.10000014305115,"secureConnectionStart":170.79999995231628},{"duration":193.09999990463257,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":170.90000009536743,"connectEnd":170.90000009536743,"connectStart":170.90000009536743,"domainLookupEnd":170.90000009536743,"domainLookupStart":170.90000009536743,"fetchStart":170.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":170.90000009536743,"responseEnd":364,"responseStart":364,"secureConnectionStart":170.90000009536743},{"duration":193.70000004768372,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2bu7/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":171,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":171,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":364.7000000476837,"responseStart":0,"secureConnectionStart":0},{"duration":193.5,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":171.20000004768372,"connectEnd":171.20000004768372,"connectStart":171.20000004768372,"domainLookupEnd":171.20000004768372,"domainLookupStart":171.20000004768372,"fetchStart":171.20000004768372,"redirectEnd":0,"redirectStart":0,"requestStart":171.20000004768372,"responseEnd":364.7000000476837,"responseStart":364.7000000476837,"secureConnectionStart":171.20000004768372},{"duration":194.80000019073486,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2bu7/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":171.29999995231628,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":171.29999995231628,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":366.10000014305115,"responseStart":0,"secureConnectionStart":0},{"duration":193.89999985694885,"initiatorType":"script","name":"https://jira.mariadb.org/s/3339d87fa2538a859872f2df449bf8d0-CDN/lu2bu7/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":171.40000009536743,"connectEnd":171.40000009536743,"connectStart":171.40000009536743,"domainLookupEnd":171.40000009536743,"domainLookupStart":171.40000009536743,"fetchStart":171.40000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":171.40000009536743,"responseEnd":365.2999999523163,"responseStart":365.2999999523163,"secureConnectionStart":171.40000009536743},{"duration":410.69999980926514,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":172.10000014305115,"connectEnd":172.10000014305115,"connectStart":172.10000014305115,"domainLookupEnd":172.10000014305115,"domainLookupStart":172.10000014305115,"fetchStart":172.10000014305115,"redirectEnd":0,"redirectStart":0,"requestStart":172.10000014305115,"responseEnd":582.7999999523163,"responseStart":582.7999999523163,"secureConnectionStart":172.10000014305115},{"duration":764,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":172.20000004768372,"connectEnd":172.20000004768372,"connectStart":172.20000004768372,"domainLookupEnd":172.20000004768372,"domainLookupStart":172.20000004768372,"fetchStart":172.20000004768372,"redirectEnd":0,"redirectStart":0,"requestStart":172.20000004768372,"responseEnd":936.2000000476837,"responseStart":936.2000000476837,"secureConnectionStart":172.20000004768372},{"duration":391.89999985694885,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":537.1000001430511,"connectEnd":537.1000001430511,"connectStart":537.1000001430511,"domainLookupEnd":537.1000001430511,"domainLookupStart":537.1000001430511,"fetchStart":537.1000001430511,"redirectEnd":0,"redirectStart":0,"requestStart":537.1000001430511,"responseEnd":929,"responseStart":929,"secureConnectionStart":537.1000001430511}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":26,"responseStart":163,"responseEnd":166,"domLoading":167,"domInteractive":958,"domContentLoadedEventStart":959,"domContentLoadedEventEnd":1005,"domComplete":2415,"loadEventStart":2415,"loadEventEnd":2416,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":939.5},{"name":"bigPipe.sidebar-id.end","time":940.2000000476837},{"name":"bigPipe.activity-panel-pipe-id.start","time":940.4000000953674},{"name":"bigPipe.activity-panel-pipe-id.end","time":942.7999999523163},{"name":"activityTabFullyLoaded","time":1018.5}],"measures":[],"correlationId":"5b1b2c594c9a55","effectiveType":"4g","downlink":9,"rtt":0,"serverDuration":69,"dbReadsTimeInMs":11,"dbConnsTimeInMs":19,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}