Skip to content

Commit a8b1f7c

Browse files
author
Jonathan Powell
committed
Fix segfault when accessing fields/field_types on freed result
Add resultFreed check to rb_mysql_result_fetch_fields and rb_mysql_result_fetch_field_types before accessing wrapper->result. The segfault occurs when: 1. A query returns 0 rows 2. Internal row caching iterates (0 iterations), never populating wrapper->fields 3. Result is freed after iteration completes 4. .fields is called, wrapper->fields is Qnil 5. mysql_num_fields(wrapper->result) accesses freed memory -> SEGFAULT This check already exists in other functions (e.g., rb_mysql_result_each_) but was missing in the fields accessor functions. Based on fix for #1426
1 parent c79b3c1 commit a8b1f7c

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

ext/mysql2/result.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,9 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {
939939
}
940940

941941
if (wrapper->fields == Qnil) {
942+
if (wrapper->resultFreed) {
943+
rb_raise(cMysql2Error, "Result set has already been freed");
944+
}
942945
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
943946
wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
944947
}
@@ -958,6 +961,9 @@ static VALUE rb_mysql_result_fetch_field_types(VALUE self) {
958961
GET_RESULT(self);
959962

960963
if (wrapper->fieldTypes == Qnil) {
964+
if (wrapper->resultFreed) {
965+
rb_raise(cMysql2Error, "Result set has already been freed");
966+
}
961967
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
962968
wrapper->fieldTypes = rb_ary_new2(wrapper->numberOfFields);
963969
}

0 commit comments

Comments
 (0)