From 1ec430d4edd90ad4ac6523b23ca669253535bc44 Mon Sep 17 00:00:00 2001 From: Danack Date: Tue, 6 Jan 2015 22:09:13 +0000 Subject: Fix #68760: Fix freeing null segfault. Added test for behaviour. --- ext/sqlite3/sqlite3.c | 17 +++++++++++------ ext/sqlite3/tests/bug68760.phpt | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 ext/sqlite3/tests/bug68760.phpt (limited to 'ext/sqlite3') diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index ca3e155e2a..bec51cc9f8 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -906,16 +906,21 @@ static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, in efree(zargs[1]); efree(zargs); - //retval ought to contain a ZVAL_LONG by now - // (the result of a comparison, i.e. most likely -1, 0, or 1) - //I suppose we could accept any scalar return type, though. - if (Z_TYPE_P(retval) != IS_LONG){ + if (!retval) { + //Exception was thrown by callback, default to 0 for compare + ret = 0; + } else if (Z_TYPE_P(retval) != IS_LONG) { + //retval ought to contain a ZVAL_LONG by now + // (the result of a comparison, i.e. most likely -1, 0, or 1) + //I suppose we could accept any scalar return type, though. php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the compare callback (invalid return type). Collation behaviour is undefined."); - }else{ + } else { ret = Z_LVAL_P(retval); } - zval_ptr_dtor(&retval); + if (retval) { + zval_ptr_dtor(&retval); + } return ret; } diff --git a/ext/sqlite3/tests/bug68760.phpt b/ext/sqlite3/tests/bug68760.phpt new file mode 100644 index 0000000000..5eb7d848bd --- /dev/null +++ b/ext/sqlite3/tests/bug68760.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #68760 (Callback throws exception behaviour. Segfault in 5.6) +--FILE-- +exec("CREATE TABLE test (col1 string)"); +$db->exec("INSERT INTO test VALUES ('a1')"); +$db->exec("INSERT INTO test VALUES ('a10')"); +$db->exec("INSERT INTO test VALUES ('a2')"); + +try { + $db->createCollation('NATURAL_CMP', 'oopsFunction'); + $naturalSort = $db->query("SELECT col1 FROM test ORDER BY col1 COLLATE NATURAL_CMP"); + while ($row = $naturalSort->fetchArray()) { + echo $row['col1'], "\n"; + } + $db->close(); +} +catch(\Exception $e) { + echo "Exception: ".$e->getMessage(); +} +?> +--EXPECTF-- +callback +Warning: SQLite3::query(): An error occurred while invoking the compare callback in %a/bug68760.php on line %i +Exception: oops + -- cgit v1.2.1 From 0c27a8eb61813f04c92caf578d24bb3b76eb6651 Mon Sep 17 00:00:00 2001 From: Danack Date: Tue, 6 Jan 2015 22:09:13 +0000 Subject: Fix #68760: Fix freeing null segfault. Added test for behaviour. --- ext/sqlite3/sqlite3.c | 17 +++++++++++------ ext/sqlite3/tests/bug68760.phpt | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 ext/sqlite3/tests/bug68760.phpt (limited to 'ext/sqlite3') diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 3ff0242cc4..8178d4f3b2 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -898,16 +898,21 @@ static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, in efree(zargs[1]); efree(zargs); - //retval ought to contain a ZVAL_LONG by now - // (the result of a comparison, i.e. most likely -1, 0, or 1) - //I suppose we could accept any scalar return type, though. - if (Z_TYPE_P(retval) != IS_LONG){ + if (!retval) { + //Exception was thrown by callback, default to 0 for compare + ret = 0; + } else if (Z_TYPE_P(retval) != IS_LONG) { + //retval ought to contain a ZVAL_LONG by now + // (the result of a comparison, i.e. most likely -1, 0, or 1) + //I suppose we could accept any scalar return type, though. php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the compare callback (invalid return type). Collation behaviour is undefined."); - }else{ + } else { ret = Z_LVAL_P(retval); } - zval_ptr_dtor(&retval); + if (retval) { + zval_ptr_dtor(&retval); + } return ret; } diff --git a/ext/sqlite3/tests/bug68760.phpt b/ext/sqlite3/tests/bug68760.phpt new file mode 100644 index 0000000000..de89a2cf22 --- /dev/null +++ b/ext/sqlite3/tests/bug68760.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #68760 (Callback throws exception behaviour. Segfault in 5.6) +--SKIPIF-- + +--FILE-- +exec("CREATE TABLE test (col1 string)"); +$db->exec("INSERT INTO test VALUES ('a1')"); +$db->exec("INSERT INTO test VALUES ('a10')"); +$db->exec("INSERT INTO test VALUES ('a2')"); + +try { + $db->createCollation('NATURAL_CMP', 'oopsFunction'); + $naturalSort = $db->query("SELECT col1 FROM test ORDER BY col1 COLLATE NATURAL_CMP"); + while ($row = $naturalSort->fetchArray()) { + echo $row['col1'], "\n"; + } + $db->close(); +} +catch(\Exception $e) { + echo "Exception: ".$e->getMessage(); +} +?> +--EXPECTF-- +callback +Warning: SQLite3::query(): An error occurred while invoking the compare callback in %a/bug68760.php on line %i +Exception: oops + -- cgit v1.2.1