Skip to content

Commit 4480e84

Browse files
mgotteinhhvm-bot
authored andcommitted
Add null checks on driver PDO statement
Summary: php5 makes all methods do nothing if there is no backing driver PDO statement Closes #4064 Reviewed By: @paulbiss Differential Revision: D1640296 Signature: t1:1640296:1414598532:2f284f59c76fa94b926251aabe2d27cd0a7de470 Pulled By: @ptarjan
1 parent 840d0df commit 4480e84

File tree

2 files changed

+142
-7
lines changed

2 files changed

+142
-7
lines changed

hphp/runtime/ext/pdo/ext_pdo.cpp

+64-3
Original file line numberDiff line numberDiff line change
@@ -2704,7 +2704,9 @@ PDOStatementData::PDOStatementData() : m_rowIndex(-1) {
27042704
}
27052705

27062706
PDOStatementData::~PDOStatementData() {
2707-
m_stmt.reset();
2707+
if (m_stmt.get() != nullptr) {
2708+
m_stmt.reset();
2709+
}
27082710
}
27092711

27102712
static Variant HHVM_METHOD(PDOStatement, execute,
@@ -2713,6 +2715,11 @@ static Variant HHVM_METHOD(PDOStatement, execute,
27132715
auto params = paramsV.isNull() ? null_array : paramsV.toArray();
27142716

27152717
SYNC_VM_REGS_SCOPED();
2718+
2719+
if (data->m_stmt.get() == nullptr) {
2720+
return init_null_variant;
2721+
}
2722+
27162723
strcpy(data->m_stmt->error_code, PDO_ERR_NONE);
27172724

27182725
if (!params.empty()) {
@@ -2792,6 +2799,11 @@ static Variant HHVM_METHOD(PDOStatement, fetch, int64_t how = 0,
27922799
auto data = Native::data<PDOStatementData>(this_);
27932800

27942801
SYNC_VM_REGS_SCOPED();
2802+
2803+
if (data->m_stmt.get() == nullptr) {
2804+
return false;
2805+
}
2806+
27952807
strcpy(data->m_stmt->error_code, PDO_ERR_NONE);
27962808
if (!pdo_stmt_verify_mode(data->m_stmt, how, false)) {
27972809
return false;
@@ -2810,6 +2822,9 @@ static Variant HHVM_METHOD(PDOStatement, fetchobject,
28102822
const String& class_name /* = null_string */,
28112823
const Variant& ctor_args /* = null */) {
28122824
auto data = Native::data<PDOStatementData>(this_);
2825+
if (data->m_stmt.get() == nullptr) {
2826+
return false;
2827+
}
28132828

28142829
strcpy(data->m_stmt->error_code, PDO_ERR_NONE);
28152830
if (!pdo_stmt_verify_mode(data->m_stmt, PDO_FETCH_CLASS, false)) {
@@ -2856,6 +2871,9 @@ static Variant HHVM_METHOD(PDOStatement, fetchobject,
28562871
static Variant HHVM_METHOD(PDOStatement, fetchcolumn,
28572872
int64_t column_numner /* = 0 */) {
28582873
auto data = Native::data<PDOStatementData>(this_);
2874+
if (data->m_stmt.get() == nullptr) {
2875+
return false;
2876+
}
28592877

28602878
strcpy(data->m_stmt->error_code, PDO_ERR_NONE);
28612879
if (!do_fetch_common(data->m_stmt, PDO_FETCH_ORI_NEXT, 0, true)) {
@@ -2871,6 +2889,9 @@ static Variant HHVM_METHOD(PDOStatement, fetchall, int64_t how /* = 0 */,
28712889
const Variant& class_name /* = null */,
28722890
const Variant& ctor_args /* = null */) {
28732891
auto self = Native::data<PDOStatementData>(this_);
2892+
if (self->m_stmt.get() == nullptr) {
2893+
return false;
2894+
}
28742895

28752896
if (!pdo_stmt_verify_mode(self->m_stmt, how, true)) {
28762897
return false;
@@ -2994,11 +3015,13 @@ static Variant HHVM_METHOD(PDOStatement, fetchall, int64_t how /* = 0 */,
29943015
return return_value;
29953016
}
29963017

2997-
29983018
static bool HHVM_METHOD(PDOStatement, bindvalue, const Variant& paramno,
29993019
const Variant& param,
30003020
int64_t type /* = q_PDO$$PARAM_STR */) {
30013021
auto data = Native::data<PDOStatementData>(this_);
3022+
if (data->m_stmt.get() == nullptr) {
3023+
return false;
3024+
}
30023025

30033026
return register_bound_param(paramno, param, type, 0,
30043027
uninit_null(), data->m_stmt, true);
@@ -3009,6 +3032,9 @@ static bool HHVM_METHOD(PDOStatement, bindparam, const Variant& paramno,
30093032
int64_t max_value_len /* = 0 */,
30103033
const Variant& driver_params /*= null */) {
30113034
auto data = Native::data<PDOStatementData>(this_);
3035+
if (data->m_stmt.get() == nullptr) {
3036+
return false;
3037+
}
30123038

30133039
return register_bound_param(paramno, ref(param), type, max_value_len,
30143040
driver_params, data->m_stmt, true);
@@ -3019,20 +3045,28 @@ static bool HHVM_METHOD(PDOStatement, bindcolumn, const Variant& paramno,
30193045
int64_t max_value_len /* = 0 */,
30203046
const Variant& driver_params /* = null */) {
30213047
auto data = Native::data<PDOStatementData>(this_);
3048+
if (data->m_stmt.get() == nullptr) {
3049+
return false;
3050+
}
30223051

30233052
return register_bound_param(paramno, ref(param), type, max_value_len,
30243053
driver_params, data->m_stmt, false);
30253054
}
30263055

30273056
static int64_t HHVM_METHOD(PDOStatement, rowcount) {
30283057
auto data = Native::data<PDOStatementData>(this_);
3058+
if (data->m_stmt.get() == nullptr) {
3059+
return 0;
3060+
}
30293061

30303062
return data->m_stmt->row_count;
30313063
}
30323064

30333065
static Variant HHVM_METHOD(PDOStatement, errorcode) {
30343066
auto data = Native::data<PDOStatementData>(this_);
3035-
3067+
if (data->m_stmt.get() == nullptr) {
3068+
return false;
3069+
}
30363070
if (data->m_stmt->error_code[0] == '\0') {
30373071
return init_null();
30383072
}
@@ -3041,6 +3075,9 @@ static Variant HHVM_METHOD(PDOStatement, errorcode) {
30413075

30423076
static Array HHVM_METHOD(PDOStatement, errorinfo) {
30433077
auto data = Native::data<PDOStatementData>(this_);
3078+
if (data->m_stmt.get() == nullptr) {
3079+
return null_array;
3080+
}
30443081

30453082
Array ret;
30463083
ret.append(String(data->m_stmt->error_code, CopyString));
@@ -3063,6 +3100,9 @@ static Array HHVM_METHOD(PDOStatement, errorinfo) {
30633100
static Variant HHVM_METHOD(PDOStatement, setattribute, int64_t attribute,
30643101
const Variant& value) {
30653102
auto data = Native::data<PDOStatementData>(this_);
3103+
if (data->m_stmt.get() == nullptr) {
3104+
return false;
3105+
}
30663106

30673107
if (!data->m_stmt->support(PDOStatement::MethodSetAttribute)) {
30683108
pdo_raise_impl_error(data->m_stmt->dbh, data->m_stmt, "IM001",
@@ -3080,6 +3120,9 @@ static Variant HHVM_METHOD(PDOStatement, setattribute, int64_t attribute,
30803120

30813121
static Variant HHVM_METHOD(PDOStatement, getattribute, int64_t attribute) {
30823122
auto data = Native::data<PDOStatementData>(this_);
3123+
if (data->m_stmt.get() == nullptr) {
3124+
return false;
3125+
}
30833126

30843127
Variant ret;
30853128
if (!data->m_stmt->support(PDOStatement::MethodGetAttribute)) {
@@ -3112,6 +3155,9 @@ static Variant HHVM_METHOD(PDOStatement, getattribute, int64_t attribute) {
31123155

31133156
static int64_t HHVM_METHOD(PDOStatement, columncount) {
31143157
auto data = Native::data<PDOStatementData>(this_);
3158+
if (data->m_stmt.get() == nullptr) {
3159+
return 0;
3160+
}
31153161

31163162
return data->m_stmt->column_count;
31173163
}
@@ -3124,6 +3170,9 @@ const StaticString
31243170

31253171
static Variant HHVM_METHOD(PDOStatement, getcolumnmeta, int64_t column) {
31263172
auto data = Native::data<PDOStatementData>(this_);
3173+
if (data->m_stmt.get() == nullptr) {
3174+
return false;
3175+
}
31273176

31283177
if (column < 0) {
31293178
pdo_raise_impl_error(data->m_stmt->dbh, data->m_stmt, "42P10",
@@ -3160,13 +3209,19 @@ static Variant HHVM_METHOD(PDOStatement, getcolumnmeta, int64_t column) {
31603209
static bool HHVM_METHOD(PDOStatement, setfetchmode,
31613210
int64_t mode, const Array& _argv /* = null_array */) {
31623211
auto data = Native::data<PDOStatementData>(this_);
3212+
if (data->m_stmt.get() == nullptr) {
3213+
return false;
3214+
}
31633215
int argc = _argv.size() + 1;
31643216

31653217
return pdo_stmt_set_fetch_mode(data->m_stmt, argc, mode, _argv);
31663218
}
31673219

31683220
static bool HHVM_METHOD(PDOStatement, nextrowset) {
31693221
auto data = Native::data<PDOStatementData>(this_);
3222+
if (data->m_stmt.get() == nullptr) {
3223+
return false;
3224+
}
31703225

31713226
if (!data->m_stmt->support(PDOStatement::MethodNextRowset)) {
31723227
pdo_raise_impl_error(data->m_stmt->dbh, data->m_stmt, "IM001",
@@ -3193,6 +3248,9 @@ static bool HHVM_METHOD(PDOStatement, nextrowset) {
31933248

31943249
static bool HHVM_METHOD(PDOStatement, closecursor) {
31953250
auto data = Native::data<PDOStatementData>(this_);
3251+
if (data->m_stmt.get() == nullptr) {
3252+
return false;
3253+
}
31963254

31973255
if (!data->m_stmt->support(PDOStatement::MethodCursorCloser)) {
31983256
/* emulate it by fetching and discarding rows */
@@ -3218,6 +3276,9 @@ static bool HHVM_METHOD(PDOStatement, closecursor) {
32183276

32193277
static Variant HHVM_METHOD(PDOStatement, debugdumpparams) {
32203278
auto data = Native::data<PDOStatementData>(this_);
3279+
if (data->m_stmt.get() == nullptr) {
3280+
return false;
3281+
}
32213282

32223283
Resource resource = File::Open("php://output", "w");
32233284
File *f = resource.getTyped<File>(true);

hphp/test/frameworks/results/paris.expect

+78-4
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,66 @@ ModelPrefixingTest::testSettingAndUnsettingStaticPropertyValue
88
.
99
ModelPrefixingTest::testStaticPropertyExists
1010
.
11+
MultipleConnectionsTest::testCustomConnectionName
12+
.
1113
MultipleConnectionsTest::testMultipleConnections
12-
FATAL
14+
.
15+
ParisTest::testBelongsToRelation
16+
.
17+
ParisTest::testBelongsToRelationWithCustomForeignKeyName
18+
.
19+
ParisTest::testBelongsToRelationWithCustomForeignKeyNameInBaseAndAssociatedTables
20+
.
1321
ParisTest::testComplexModelClassName
1422
.
1523
ParisTest::testCustomIDColumn
16-
FATAL
24+
.
25+
ParisTest::testDeleteData
26+
.
27+
ParisTest::testFilterWithArguments
28+
.
29+
ParisTest::testFilterWithNoArguments
30+
.
31+
ParisTest::testFindResultSet
32+
.
33+
ParisTest::testHasManyRelation
34+
.
35+
ParisTest::testHasManyRelationWithCustomForeignKeyName
36+
.
37+
ParisTest::testHasManyRelationWithCustomForeignKeyNameInBaseAndAssociatedTables
38+
.
39+
ParisTest::testHasManyThroughRelation
40+
.
41+
ParisTest::testHasManyThroughRelationWithCustomIntermediateModelAndKeyNames
42+
.
43+
ParisTest::testHasManyThroughRelationWithCustomIntermediateModelAndKeyNamesAndCustomForeignKeyInAssociatedTable
44+
.
45+
ParisTest::testHasManyThroughRelationWithCustomIntermediateModelAndKeyNamesAndCustomForeignKeyInBaseAndAssociatedTables
46+
.
47+
ParisTest::testHasManyThroughRelationWithCustomIntermediateModelAndKeyNamesAndCustomForeignKeyInBaseTable
48+
.
49+
ParisTest::testHasOneRelation
50+
.
51+
ParisTest::testHasOneWithCustomForeignKeyName
52+
.
53+
ParisTest::testHasOneWithCustomForeignKeyNameInBaseAndAssociatedTables
54+
.
55+
ParisTest::testInsertData
56+
.
57+
ParisTest::testInsertingDataContainingAnExpression
58+
.
59+
ParisTest::testInvalidModelFunctionCallDoesNotRecurse
60+
.
61+
ParisTest::testInvalidORMWrapperFunctionCallDoesNotRecurse
62+
.
63+
ParisTest::testIssue80RecursiveErrorFromInstantiatingModelClass
64+
.
1765
ParisTest::testModelWithCustomTable
1866
.
1967
ParisTest::testSimpleAutoTableName
2068
.
69+
ParisTest::testUpdateData
70+
.
2171
Paris\Tests\ModelPrefixingTest53::testNamespacePrefixSwitching
2272
.
2373
Paris\Tests\ModelPrefixingTest53::testNoPrefixOnAutoTableName
@@ -27,7 +77,9 @@ Paris\Tests\ModelPrefixingTest53::testPrefixOnAutoTableName
2777
Paris\Tests\ModelPrefixingTest53::testPrefixOnAutoTableNameWithTableSpecified
2878
.
2979
Paris\Tests\ModelPrefixingTest53::testPrefixOnHasManyThroughRelation
30-
FATAL
80+
.
81+
Paris\Tests\ModelPrefixingTest53::testPrefixOnHasManyThroughRelationWithCustomIntermediateModelAndKeyNames
82+
.
3183
Paris\Tests\ParisTest53::testIgnoredNamespaceTableName
3284
.
3385
Paris\Tests\ParisTest53::testModelWithCustomTable
@@ -36,5 +88,27 @@ Paris\Tests\ParisTest53::testNamespacedTableName
3688
.
3789
Paris\Tests\ParisTest53::testShortcut
3890
.
91+
Psr1Test53::testBelongsToRelation
92+
.
93+
Psr1Test53::testBelongsToRelationWithCustomForeignKeyName
94+
.
95+
Psr1Test53::testDeleteData
96+
.
97+
Psr1Test53::testHasManyRelation
98+
.
99+
Psr1Test53::testHasManyRelationWithCustomForeignKeyName
100+
.
101+
Psr1Test53::testHasManyThroughRelation
102+
.
103+
Psr1Test53::testHasManyThroughRelationWithCustomIntermediateModelAndKeyNames
104+
.
105+
Psr1Test53::testHasOneRelation
106+
.
107+
Psr1Test53::testHasOneWithCustomForeignKeyName
108+
.
39109
Psr1Test53::testInsertData
40-
FATAL
110+
.
111+
Psr1Test53::testInsertingDataContainingAnExpression
112+
.
113+
Psr1Test53::testUpdateData
114+
.

0 commit comments

Comments
 (0)