@@ -3297,8 +3297,14 @@ PHP_FUNCTION(pg_escape_string)
3297
3297
3298
3298
to = zend_string_safe_alloc (ZSTR_LEN (from ), 2 , 0 , 0 );
3299
3299
if (link ) {
3300
+ int err ;
3300
3301
pgsql = link -> conn ;
3301
- ZSTR_LEN (to ) = PQescapeStringConn (pgsql , ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ), NULL );
3302
+ ZSTR_LEN (to ) = PQescapeStringConn (pgsql , ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ), & err );
3303
+ if (err ) {
3304
+ zend_argument_value_error (ZEND_NUM_ARGS (), "Escaping string failed" );
3305
+ zend_string_efree (to );
3306
+ RETURN_THROWS ();
3307
+ }
3302
3308
} else
3303
3309
{
3304
3310
ZSTR_LEN (to ) = PQescapeString (ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ));
@@ -3341,6 +3347,10 @@ PHP_FUNCTION(pg_escape_bytea)
3341
3347
} else {
3342
3348
to = (char * )PQescapeBytea ((unsigned char * )ZSTR_VAL (from ), ZSTR_LEN (from ), & to_len );
3343
3349
}
3350
+ if (to == NULL ) {
3351
+ zend_argument_value_error (ZEND_NUM_ARGS (), "Escape failure" );
3352
+ RETURN_THROWS ();
3353
+ }
3344
3354
3345
3355
RETVAL_STRINGL (to , to_len - 1 ); /* to_len includes additional '\0' */
3346
3356
PQfreemem (to );
@@ -4257,7 +4267,7 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4257
4267
char * escaped ;
4258
4268
smart_str querystr = {0 };
4259
4269
size_t new_len ;
4260
- int i , num_rows ;
4270
+ int i , num_rows , err ;
4261
4271
zval elem ;
4262
4272
4263
4273
ZEND_ASSERT (ZSTR_LEN (table_name ) != 0 );
@@ -4296,15 +4306,29 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4296
4306
"WHERE a.attnum > 0 AND c.relname = '" );
4297
4307
}
4298
4308
escaped = (char * )safe_emalloc (strlen (tmp_name2 ), 2 , 1 );
4299
- new_len = PQescapeStringConn (pg_link , escaped , tmp_name2 , strlen (tmp_name2 ), NULL );
4309
+ new_len = PQescapeStringConn (pg_link , escaped , tmp_name2 , strlen (tmp_name2 ), & err );
4310
+ if (err ) {
4311
+ php_error_docref (NULL , E_WARNING , "Escaping table name '%s' failed" , ZSTR_VAL (table_name ));
4312
+ efree (src );
4313
+ efree (escaped );
4314
+ smart_str_free (& querystr );
4315
+ return FAILURE ;
4316
+ }
4300
4317
if (new_len ) {
4301
4318
smart_str_appendl (& querystr , escaped , new_len );
4302
4319
}
4303
4320
efree (escaped );
4304
4321
4305
4322
smart_str_appends (& querystr , "' AND n.nspname = '" );
4306
4323
escaped = (char * )safe_emalloc (strlen (tmp_name ), 2 , 1 );
4307
- new_len = PQescapeStringConn (pg_link , escaped , tmp_name , strlen (tmp_name ), NULL );
4324
+ new_len = PQescapeStringConn (pg_link , escaped , tmp_name , strlen (tmp_name ), & err );
4325
+ if (err ) {
4326
+ php_error_docref (NULL , E_WARNING , "Escaping table namespace '%s' failed" , ZSTR_VAL (table_name ));
4327
+ efree (src );
4328
+ efree (escaped );
4329
+ smart_str_free (& querystr );
4330
+ return FAILURE ;
4331
+ }
4308
4332
if (new_len ) {
4309
4333
smart_str_appendl (& querystr , escaped , new_len );
4310
4334
}
@@ -4565,7 +4589,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
4565
4589
{
4566
4590
zend_string * field = NULL ;
4567
4591
zval meta , * def , * type , * not_null , * has_default , * is_enum , * val , new_val ;
4568
- int err = 0 , skip_field ;
4592
+ int err = 0 , escape_err = 0 , skip_field ;
4569
4593
php_pgsql_data_type data_type ;
4570
4594
4571
4595
ZEND_ASSERT (pg_link != NULL );
@@ -4818,8 +4842,13 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
4818
4842
/* PostgreSQL ignores \0 */
4819
4843
str = zend_string_alloc (Z_STRLEN_P (val ) * 2 , 0 );
4820
4844
/* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */
4821
- ZSTR_LEN (str ) = PQescapeStringConn (pg_link , ZSTR_VAL (str ), Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
4822
- ZVAL_STR (& new_val , php_pgsql_add_quotes (str ));
4845
+ ZSTR_LEN (str ) = PQescapeStringConn (pg_link , ZSTR_VAL (str ),
4846
+ Z_STRVAL_P (val ), Z_STRLEN_P (val ), & escape_err );
4847
+ if (escape_err ) {
4848
+ err = 1 ;
4849
+ } else {
4850
+ ZVAL_STR (& new_val , php_pgsql_add_quotes (str ));
4851
+ }
4823
4852
zend_string_release_ex (str , false);
4824
4853
}
4825
4854
break ;
@@ -4842,7 +4871,15 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
4842
4871
}
4843
4872
PGSQL_CONV_CHECK_IGNORE ();
4844
4873
if (err ) {
4845
- php_error_docref (NULL , E_NOTICE , "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)" , Z_STRVAL_P (type ), ZSTR_VAL (field ));
4874
+ if (escape_err ) {
4875
+ php_error_docref (NULL , E_NOTICE ,
4876
+ "String value escaping failed for PostgreSQL '%s' (%s)" ,
4877
+ Z_STRVAL_P (type ), ZSTR_VAL (field ));
4878
+ } else {
4879
+ php_error_docref (NULL , E_NOTICE ,
4880
+ "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)" ,
4881
+ Z_STRVAL_P (type ), ZSTR_VAL (field ));
4882
+ }
4846
4883
}
4847
4884
break ;
4848
4885
@@ -5113,6 +5150,11 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5113
5150
zend_string * tmp_zstr ;
5114
5151
5115
5152
tmp = PQescapeByteaConn (pg_link , (unsigned char * )Z_STRVAL_P (val ), Z_STRLEN_P (val ), & to_len );
5153
+ if (tmp == NULL ) {
5154
+ php_error_docref (NULL , E_NOTICE , "Escaping value failed for %s field (%s)" , Z_STRVAL_P (type ), ZSTR_VAL (field ));
5155
+ err = 1 ;
5156
+ break ;
5157
+ }
5116
5158
tmp_zstr = zend_string_init ((char * )tmp , to_len - 1 , false); /* PQescapeBytea's to_len includes additional '\0' */
5117
5159
PQfreemem (tmp );
5118
5160
@@ -5191,6 +5233,12 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5191
5233
zend_hash_update (Z_ARRVAL_P (result ), field , & new_val );
5192
5234
} else {
5193
5235
char * escaped = PQescapeIdentifier (pg_link , ZSTR_VAL (field ), ZSTR_LEN (field ));
5236
+ if (escaped == NULL ) {
5237
+ /* This cannot fail because of invalid string but only due to failed memory allocation */
5238
+ php_error_docref (NULL , E_NOTICE , "Escaping field '%s' failed" , ZSTR_VAL (field ));
5239
+ err = 1 ;
5240
+ break ;
5241
+ }
5194
5242
add_assoc_zval (result , escaped , & new_val );
5195
5243
PQfreemem (escaped );
5196
5244
}
@@ -5269,7 +5317,7 @@ static bool do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link,
5269
5317
}
5270
5318
/* }}} */
5271
5319
5272
- static inline void build_tablename (smart_str * querystr , PGconn * pg_link , const zend_string * table ) /* {{{ */
5320
+ static inline zend_result build_tablename (smart_str * querystr , PGconn * pg_link , const zend_string * table ) /* {{{ */
5273
5321
{
5274
5322
/* schema.table should be "schema"."table" */
5275
5323
const char * dot = memchr (ZSTR_VAL (table ), '.' , ZSTR_LEN (table ));
@@ -5279,6 +5327,10 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z
5279
5327
smart_str_appendl (querystr , ZSTR_VAL (table ), len );
5280
5328
} else {
5281
5329
char * escaped = PQescapeIdentifier (pg_link , ZSTR_VAL (table ), len );
5330
+ if (escaped == NULL ) {
5331
+ php_error_docref (NULL , E_NOTICE , "Failed to escape table name '%s'" , ZSTR_VAL (table ));
5332
+ return FAILURE ;
5333
+ }
5282
5334
smart_str_appends (querystr , escaped );
5283
5335
PQfreemem (escaped );
5284
5336
}
@@ -5291,11 +5343,17 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z
5291
5343
smart_str_appendl (querystr , after_dot , len );
5292
5344
} else {
5293
5345
char * escaped = PQescapeIdentifier (pg_link , after_dot , len );
5346
+ if (escaped == NULL ) {
5347
+ php_error_docref (NULL , E_NOTICE , "Failed to escape table name '%s'" , ZSTR_VAL (table ));
5348
+ return FAILURE ;
5349
+ }
5294
5350
smart_str_appendc (querystr , '.' );
5295
5351
smart_str_appends (querystr , escaped );
5296
5352
PQfreemem (escaped );
5297
5353
}
5298
5354
}
5355
+
5356
+ return SUCCESS ;
5299
5357
}
5300
5358
/* }}} */
5301
5359
@@ -5316,7 +5374,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5316
5374
ZVAL_UNDEF (& converted );
5317
5375
if (zend_hash_num_elements (Z_ARRVAL_P (var_array )) == 0 ) {
5318
5376
smart_str_appends (& querystr , "INSERT INTO " );
5319
- build_tablename (& querystr , pg_link , table );
5377
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5378
+ goto cleanup ;
5379
+ }
5320
5380
smart_str_appends (& querystr , " DEFAULT VALUES" );
5321
5381
5322
5382
goto no_values ;
@@ -5332,7 +5392,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5332
5392
}
5333
5393
5334
5394
smart_str_appends (& querystr , "INSERT INTO " );
5335
- build_tablename (& querystr , pg_link , table );
5395
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5396
+ goto cleanup ;
5397
+ }
5336
5398
smart_str_appends (& querystr , " (" );
5337
5399
5338
5400
ZEND_HASH_FOREACH_STR_KEY (Z_ARRVAL_P (var_array ), fld ) {
@@ -5342,6 +5404,10 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5342
5404
}
5343
5405
if (opt & PGSQL_DML_ESCAPE ) {
5344
5406
tmp = PQescapeIdentifier (pg_link , ZSTR_VAL (fld ), ZSTR_LEN (fld ) + 1 );
5407
+ if (tmp == NULL ) {
5408
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s'" , ZSTR_VAL (fld ));
5409
+ goto cleanup ;
5410
+ }
5345
5411
smart_str_appends (& querystr , tmp );
5346
5412
PQfreemem (tmp );
5347
5413
} else {
@@ -5353,15 +5419,19 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5353
5419
smart_str_appends (& querystr , ") VALUES (" );
5354
5420
5355
5421
/* make values string */
5356
- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (var_array ), val ) {
5422
+ ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (var_array ), fld , val ) {
5357
5423
/* we can avoid the key_type check here, because we tested it in the other loop */
5358
5424
switch (Z_TYPE_P (val )) {
5359
5425
case IS_STRING :
5360
5426
if (opt & PGSQL_DML_ESCAPE ) {
5361
- size_t new_len ;
5362
- char * tmp ;
5363
- tmp = (char * )safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5364
- new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5427
+ int error ;
5428
+ char * tmp = safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5429
+ size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), & error );
5430
+ if (error ) {
5431
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s' value" , ZSTR_VAL (fld ));
5432
+ efree (tmp );
5433
+ goto cleanup ;
5434
+ }
5365
5435
smart_str_appendc (& querystr , '\'' );
5366
5436
smart_str_appendl (& querystr , tmp , new_len );
5367
5437
smart_str_appendc (& querystr , '\'' );
@@ -5517,6 +5587,10 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
5517
5587
}
5518
5588
if (opt & PGSQL_DML_ESCAPE ) {
5519
5589
char * tmp = PQescapeIdentifier (pg_link , ZSTR_VAL (fld ), ZSTR_LEN (fld ) + 1 );
5590
+ if (tmp == NULL ) {
5591
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s'" , ZSTR_VAL (fld ));
5592
+ return -1 ;
5593
+ }
5520
5594
smart_str_appends (querystr , tmp );
5521
5595
PQfreemem (tmp );
5522
5596
} else {
@@ -5532,8 +5606,14 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
5532
5606
switch (Z_TYPE_P (val )) {
5533
5607
case IS_STRING :
5534
5608
if (opt & PGSQL_DML_ESCAPE ) {
5609
+ int error ;
5535
5610
char * tmp = (char * )safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5536
- size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5611
+ size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), & error );
5612
+ if (error ) {
5613
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s' value" , ZSTR_VAL (fld ));
5614
+ efree (tmp );
5615
+ return -1 ;
5616
+ }
5537
5617
smart_str_appendc (querystr , '\'' );
5538
5618
smart_str_appendl (querystr , tmp , new_len );
5539
5619
smart_str_appendc (querystr , '\'' );
@@ -5601,7 +5681,9 @@ PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *t
5601
5681
}
5602
5682
5603
5683
smart_str_appends (& querystr , "UPDATE " );
5604
- build_tablename (& querystr , pg_link , table );
5684
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5685
+ goto cleanup ;
5686
+ }
5605
5687
smart_str_appends (& querystr , " SET " );
5606
5688
5607
5689
if (build_assignment_string (pg_link , & querystr , Z_ARRVAL_P (var_array ), 0 , "," , 1 , opt ))
@@ -5704,7 +5786,9 @@ PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *t
5704
5786
}
5705
5787
5706
5788
smart_str_appends (& querystr , "DELETE FROM " );
5707
- build_tablename (& querystr , pg_link , table );
5789
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5790
+ goto cleanup ;
5791
+ }
5708
5792
smart_str_appends (& querystr , " WHERE " );
5709
5793
5710
5794
if (build_assignment_string (pg_link , & querystr , Z_ARRVAL_P (ids_array ), 1 , " AND " , sizeof (" AND " )- 1 , opt ))
@@ -5844,7 +5928,9 @@ PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *t
5844
5928
}
5845
5929
5846
5930
smart_str_appends (& querystr , "SELECT * FROM " );
5847
- build_tablename (& querystr , pg_link , table );
5931
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5932
+ goto cleanup ;
5933
+ }
5848
5934
smart_str_appends (& querystr , " WHERE " );
5849
5935
5850
5936
if (build_assignment_string (pg_link , & querystr , Z_ARRVAL_P (ids_array ), 1 , " AND " , sizeof (" AND " )- 1 , opt ))
0 commit comments