@@ -3528,8 +3528,14 @@ PHP_FUNCTION(pg_escape_string)
3528
3528
3529
3529
to = zend_string_safe_alloc (ZSTR_LEN (from ), 2 , 0 , 0 );
3530
3530
if (link ) {
3531
+ int err ;
3531
3532
pgsql = link -> conn ;
3532
- ZSTR_LEN (to ) = PQescapeStringConn (pgsql , ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ), NULL );
3533
+ ZSTR_LEN (to ) = PQescapeStringConn (pgsql , ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ), & err );
3534
+ if (err ) {
3535
+ zend_argument_value_error (ZEND_NUM_ARGS (), "Escaping string failed" );
3536
+ zend_string_efree (to );
3537
+ RETURN_THROWS ();
3538
+ }
3533
3539
} else
3534
3540
{
3535
3541
ZSTR_LEN (to ) = PQescapeString (ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ));
@@ -3575,6 +3581,10 @@ PHP_FUNCTION(pg_escape_bytea)
3575
3581
} else {
3576
3582
to = (char * )PQescapeBytea ((unsigned char * )ZSTR_VAL (from ), ZSTR_LEN (from ), & to_len );
3577
3583
}
3584
+ if (to == NULL ) {
3585
+ zend_argument_value_error (ZEND_NUM_ARGS (), "Escape failure" );
3586
+ RETURN_THROWS ();
3587
+ }
3578
3588
3579
3589
RETVAL_STRINGL (to , to_len - 1 ); /* to_len includes additional '\0' */
3580
3590
PQfreemem (to );
@@ -4523,7 +4533,7 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4523
4533
char * escaped ;
4524
4534
smart_str querystr = {0 };
4525
4535
size_t new_len , len ;
4526
- int i , num_rows ;
4536
+ int i , num_rows , err ;
4527
4537
zval elem ;
4528
4538
4529
4539
ZEND_ASSERT (ZSTR_LEN (table_name ) != 0 );
@@ -4562,7 +4572,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4562
4572
}
4563
4573
len = strlen (tmp_name2 );
4564
4574
escaped = (char * )safe_emalloc (len , 2 , 1 );
4565
- new_len = PQescapeStringConn (pg_link , escaped , tmp_name2 , len , NULL );
4575
+ new_len = PQescapeStringConn (pg_link , escaped , tmp_name2 , len , & err );
4576
+ if (err ) {
4577
+ php_error_docref (NULL , E_WARNING , "Escaping table name '%s' failed" , ZSTR_VAL (table_name ));
4578
+ efree (src );
4579
+ efree (escaped );
4580
+ smart_str_free (& querystr );
4581
+ return FAILURE ;
4582
+ }
4566
4583
if (new_len ) {
4567
4584
smart_str_appendl (& querystr , escaped , new_len );
4568
4585
}
@@ -4571,7 +4588,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4571
4588
smart_str_appends (& querystr , "' AND n.nspname = '" );
4572
4589
len = strlen (tmp_name );
4573
4590
escaped = (char * )safe_emalloc (len , 2 , 1 );
4574
- new_len = PQescapeStringConn (pg_link , escaped , tmp_name , len , NULL );
4591
+ new_len = PQescapeStringConn (pg_link , escaped , tmp_name , len , & err );
4592
+ if (err ) {
4593
+ php_error_docref (NULL , E_WARNING , "Escaping table namespace '%s' failed" , ZSTR_VAL (table_name ));
4594
+ efree (src );
4595
+ efree (escaped );
4596
+ smart_str_free (& querystr );
4597
+ return FAILURE ;
4598
+ }
4575
4599
if (new_len ) {
4576
4600
smart_str_appendl (& querystr , escaped , new_len );
4577
4601
}
@@ -4826,7 +4850,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
4826
4850
{
4827
4851
zend_string * field = NULL ;
4828
4852
zval meta , * def , * type , * not_null , * has_default , * is_enum , * val , new_val ;
4829
- int err = 0 , skip_field ;
4853
+ int err = 0 , escape_err = 0 , skip_field ;
4830
4854
php_pgsql_data_type data_type ;
4831
4855
4832
4856
ZEND_ASSERT (pg_link != NULL );
@@ -5072,8 +5096,13 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5072
5096
/* PostgreSQL ignores \0 */
5073
5097
str = zend_string_alloc (Z_STRLEN_P (val ) * 2 , 0 );
5074
5098
/* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */
5075
- ZSTR_LEN (str ) = PQescapeStringConn (pg_link , ZSTR_VAL (str ), Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5076
- ZVAL_STR (& new_val , php_pgsql_add_quotes (str ));
5099
+ ZSTR_LEN (str ) = PQescapeStringConn (pg_link , ZSTR_VAL (str ),
5100
+ Z_STRVAL_P (val ), Z_STRLEN_P (val ), & escape_err );
5101
+ if (escape_err ) {
5102
+ err = 1 ;
5103
+ } else {
5104
+ ZVAL_STR (& new_val , php_pgsql_add_quotes (str ));
5105
+ }
5077
5106
zend_string_release_ex (str , false);
5078
5107
}
5079
5108
break ;
@@ -5096,7 +5125,14 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5096
5125
}
5097
5126
PGSQL_CONV_CHECK_IGNORE ();
5098
5127
if (err ) {
5099
- zend_type_error ("%s(): Field \"%s\" must be of type string|null, %s given" , get_active_function_name (), ZSTR_VAL (field ), Z_STRVAL_P (type ));
5128
+ if (escape_err ) {
5129
+ php_error_docref (NULL , E_NOTICE ,
5130
+ "String value escaping failed for PostgreSQL '%s' (%s)" ,
5131
+ Z_STRVAL_P (type ), ZSTR_VAL (field ));
5132
+ } else {
5133
+ zend_type_error ("%s(): Field \"%s\" must be of type string|null, %s given" ,
5134
+ get_active_function_name (), ZSTR_VAL (field ), Z_STRVAL_P (type ));
5135
+ }
5100
5136
}
5101
5137
break ;
5102
5138
@@ -5330,6 +5366,11 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5330
5366
zend_string * tmp_zstr ;
5331
5367
5332
5368
tmp = PQescapeByteaConn (pg_link , (unsigned char * )Z_STRVAL_P (val ), Z_STRLEN_P (val ), & to_len );
5369
+ if (tmp == NULL ) {
5370
+ php_error_docref (NULL , E_NOTICE , "Escaping value failed for %s field (%s)" , Z_STRVAL_P (type ), ZSTR_VAL (field ));
5371
+ err = 1 ;
5372
+ break ;
5373
+ }
5333
5374
tmp_zstr = zend_string_init ((char * )tmp , to_len - 1 , false); /* PQescapeBytea's to_len includes additional '\0' */
5334
5375
PQfreemem (tmp );
5335
5376
@@ -5406,6 +5447,12 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5406
5447
zend_hash_update (Z_ARRVAL_P (result ), field , & new_val );
5407
5448
} else {
5408
5449
char * escaped = PQescapeIdentifier (pg_link , ZSTR_VAL (field ), ZSTR_LEN (field ));
5450
+ if (escaped == NULL ) {
5451
+ /* This cannot fail because of invalid string but only due to failed memory allocation */
5452
+ php_error_docref (NULL , E_NOTICE , "Escaping field '%s' failed" , ZSTR_VAL (field ));
5453
+ err = 1 ;
5454
+ break ;
5455
+ }
5409
5456
add_assoc_zval (result , escaped , & new_val );
5410
5457
PQfreemem (escaped );
5411
5458
}
@@ -5488,7 +5535,7 @@ static bool do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link,
5488
5535
}
5489
5536
/* }}} */
5490
5537
5491
- static inline void build_tablename (smart_str * querystr , PGconn * pg_link , const zend_string * table ) /* {{{ */
5538
+ static inline zend_result build_tablename (smart_str * querystr , PGconn * pg_link , const zend_string * table ) /* {{{ */
5492
5539
{
5493
5540
/* schema.table should be "schema"."table" */
5494
5541
const char * dot = memchr (ZSTR_VAL (table ), '.' , ZSTR_LEN (table ));
@@ -5498,6 +5545,10 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z
5498
5545
smart_str_appendl (querystr , ZSTR_VAL (table ), len );
5499
5546
} else {
5500
5547
char * escaped = PQescapeIdentifier (pg_link , ZSTR_VAL (table ), len );
5548
+ if (escaped == NULL ) {
5549
+ php_error_docref (NULL , E_NOTICE , "Failed to escape table name '%s'" , ZSTR_VAL (table ));
5550
+ return FAILURE ;
5551
+ }
5501
5552
smart_str_appends (querystr , escaped );
5502
5553
PQfreemem (escaped );
5503
5554
}
@@ -5510,11 +5561,17 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z
5510
5561
smart_str_appendl (querystr , after_dot , len );
5511
5562
} else {
5512
5563
char * escaped = PQescapeIdentifier (pg_link , after_dot , len );
5564
+ if (escaped == NULL ) {
5565
+ php_error_docref (NULL , E_NOTICE , "Failed to escape table name '%s'" , ZSTR_VAL (table ));
5566
+ return FAILURE ;
5567
+ }
5513
5568
smart_str_appendc (querystr , '.' );
5514
5569
smart_str_appends (querystr , escaped );
5515
5570
PQfreemem (escaped );
5516
5571
}
5517
5572
}
5573
+
5574
+ return SUCCESS ;
5518
5575
}
5519
5576
/* }}} */
5520
5577
@@ -5535,7 +5592,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5535
5592
ZVAL_UNDEF (& converted );
5536
5593
if (zend_hash_num_elements (Z_ARRVAL_P (var_array )) == 0 ) {
5537
5594
smart_str_appends (& querystr , "INSERT INTO " );
5538
- build_tablename (& querystr , pg_link , table );
5595
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5596
+ goto cleanup ;
5597
+ }
5539
5598
smart_str_appends (& querystr , " DEFAULT VALUES" );
5540
5599
5541
5600
goto no_values ;
@@ -5551,7 +5610,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5551
5610
}
5552
5611
5553
5612
smart_str_appends (& querystr , "INSERT INTO " );
5554
- build_tablename (& querystr , pg_link , table );
5613
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5614
+ goto cleanup ;
5615
+ }
5555
5616
smart_str_appends (& querystr , " (" );
5556
5617
5557
5618
ZEND_HASH_FOREACH_STR_KEY (Z_ARRVAL_P (var_array ), fld ) {
@@ -5561,6 +5622,10 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5561
5622
}
5562
5623
if (opt & PGSQL_DML_ESCAPE ) {
5563
5624
tmp = PQescapeIdentifier (pg_link , ZSTR_VAL (fld ), ZSTR_LEN (fld ) + 1 );
5625
+ if (tmp == NULL ) {
5626
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s'" , ZSTR_VAL (fld ));
5627
+ goto cleanup ;
5628
+ }
5564
5629
smart_str_appends (& querystr , tmp );
5565
5630
PQfreemem (tmp );
5566
5631
} else {
@@ -5572,15 +5637,19 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5572
5637
smart_str_appends (& querystr , ") VALUES (" );
5573
5638
5574
5639
/* make values string */
5575
- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (var_array ), val ) {
5640
+ ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (var_array ), fld , val ) {
5576
5641
/* we can avoid the key_type check here, because we tested it in the other loop */
5577
5642
switch (Z_TYPE_P (val )) {
5578
5643
case IS_STRING :
5579
5644
if (opt & PGSQL_DML_ESCAPE ) {
5580
- size_t new_len ;
5581
- char * tmp ;
5582
- tmp = (char * )safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5583
- new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5645
+ int error ;
5646
+ char * tmp = safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5647
+ size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), & error );
5648
+ if (error ) {
5649
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s' value" , ZSTR_VAL (fld ));
5650
+ efree (tmp );
5651
+ goto cleanup ;
5652
+ }
5584
5653
smart_str_appendc (& querystr , '\'' );
5585
5654
smart_str_appendl (& querystr , tmp , new_len );
5586
5655
smart_str_appendc (& querystr , '\'' );
@@ -5738,6 +5807,10 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
5738
5807
}
5739
5808
if (opt & PGSQL_DML_ESCAPE ) {
5740
5809
char * tmp = PQescapeIdentifier (pg_link , ZSTR_VAL (fld ), ZSTR_LEN (fld ) + 1 );
5810
+ if (tmp == NULL ) {
5811
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s'" , ZSTR_VAL (fld ));
5812
+ return -1 ;
5813
+ }
5741
5814
smart_str_appends (querystr , tmp );
5742
5815
PQfreemem (tmp );
5743
5816
} else {
@@ -5753,8 +5826,14 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
5753
5826
switch (Z_TYPE_P (val )) {
5754
5827
case IS_STRING :
5755
5828
if (opt & PGSQL_DML_ESCAPE ) {
5829
+ int error ;
5756
5830
char * tmp = (char * )safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5757
- size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5831
+ size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), & error );
5832
+ if (error ) {
5833
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s' value" , ZSTR_VAL (fld ));
5834
+ efree (tmp );
5835
+ return -1 ;
5836
+ }
5758
5837
smart_str_appendc (querystr , '\'' );
5759
5838
smart_str_appendl (querystr , tmp , new_len );
5760
5839
smart_str_appendc (querystr , '\'' );
@@ -5822,7 +5901,9 @@ PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *t
5822
5901
}
5823
5902
5824
5903
smart_str_appends (& querystr , "UPDATE " );
5825
- build_tablename (& querystr , pg_link , table );
5904
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5905
+ goto cleanup ;
5906
+ }
5826
5907
smart_str_appends (& querystr , " SET " );
5827
5908
5828
5909
if (build_assignment_string (pg_link , & querystr , Z_ARRVAL_P (var_array ), 0 , "," , 1 , opt ))
@@ -5928,7 +6009,9 @@ PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *t
5928
6009
}
5929
6010
5930
6011
smart_str_appends (& querystr , "DELETE FROM " );
5931
- build_tablename (& querystr , pg_link , table );
6012
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
6013
+ goto cleanup ;
6014
+ }
5932
6015
smart_str_appends (& querystr , " WHERE " );
5933
6016
5934
6017
if (build_assignment_string (pg_link , & querystr , Z_ARRVAL_P (ids_array ), 1 , " AND " , sizeof (" AND " )- 1 , opt ))
@@ -6072,7 +6155,9 @@ PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *t
6072
6155
}
6073
6156
6074
6157
smart_str_appends (& querystr , "SELECT * FROM " );
6075
- build_tablename (& querystr , pg_link , table );
6158
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
6159
+ goto cleanup ;
6160
+ }
6076
6161
6077
6162
if (is_valid_ids_array ) {
6078
6163
smart_str_appends (& querystr , " WHERE " );
0 commit comments