@@ -3572,8 +3572,14 @@ PHP_FUNCTION(pg_escape_string)
3572
3572
3573
3573
to = zend_string_safe_alloc (ZSTR_LEN (from ), 2 , 0 , 0 );
3574
3574
if (link ) {
3575
+ int err ;
3575
3576
pgsql = link -> conn ;
3576
- ZSTR_LEN (to ) = PQescapeStringConn (pgsql , ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ), NULL );
3577
+ ZSTR_LEN (to ) = PQescapeStringConn (pgsql , ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ), & err );
3578
+ if (err ) {
3579
+ zend_argument_value_error (ZEND_NUM_ARGS (), "Escaping string failed" );
3580
+ zend_string_efree (to );
3581
+ RETURN_THROWS ();
3582
+ }
3577
3583
} else
3578
3584
{
3579
3585
ZSTR_LEN (to ) = PQescapeString (ZSTR_VAL (to ), ZSTR_VAL (from ), ZSTR_LEN (from ));
@@ -3619,6 +3625,10 @@ PHP_FUNCTION(pg_escape_bytea)
3619
3625
} else {
3620
3626
to = (char * )PQescapeBytea ((unsigned char * )ZSTR_VAL (from ), ZSTR_LEN (from ), & to_len );
3621
3627
}
3628
+ if (to == NULL ) {
3629
+ zend_argument_value_error (ZEND_NUM_ARGS (), "Escape failure" );
3630
+ RETURN_THROWS ();
3631
+ }
3622
3632
3623
3633
RETVAL_STRINGL (to , to_len - 1 ); /* to_len includes additional '\0' */
3624
3634
PQfreemem (to );
@@ -4572,7 +4582,7 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4572
4582
char * escaped ;
4573
4583
smart_str querystr = {0 };
4574
4584
size_t new_len , len ;
4575
- int i , num_rows ;
4585
+ int i , num_rows , err ;
4576
4586
zval elem ;
4577
4587
4578
4588
ZEND_ASSERT (ZSTR_LEN (table_name ) != 0 );
@@ -4611,7 +4621,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4611
4621
}
4612
4622
len = strlen (tmp_name2 );
4613
4623
escaped = (char * )safe_emalloc (len , 2 , 1 );
4614
- new_len = PQescapeStringConn (pg_link , escaped , tmp_name2 , len , NULL );
4624
+ new_len = PQescapeStringConn (pg_link , escaped , tmp_name2 , len , & err );
4625
+ if (err ) {
4626
+ php_error_docref (NULL , E_WARNING , "Escaping table name '%s' failed" , ZSTR_VAL (table_name ));
4627
+ efree (src );
4628
+ efree (escaped );
4629
+ smart_str_free (& querystr );
4630
+ return FAILURE ;
4631
+ }
4615
4632
if (new_len ) {
4616
4633
smart_str_appendl (& querystr , escaped , new_len );
4617
4634
}
@@ -4620,7 +4637,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
4620
4637
smart_str_appends (& querystr , "' AND n.nspname = '" );
4621
4638
len = strlen (tmp_name );
4622
4639
escaped = (char * )safe_emalloc (len , 2 , 1 );
4623
- new_len = PQescapeStringConn (pg_link , escaped , tmp_name , len , NULL );
4640
+ new_len = PQescapeStringConn (pg_link , escaped , tmp_name , len , & err );
4641
+ if (err ) {
4642
+ php_error_docref (NULL , E_WARNING , "Escaping table namespace '%s' failed" , ZSTR_VAL (table_name ));
4643
+ efree (src );
4644
+ efree (escaped );
4645
+ smart_str_free (& querystr );
4646
+ return FAILURE ;
4647
+ }
4624
4648
if (new_len ) {
4625
4649
smart_str_appendl (& querystr , escaped , new_len );
4626
4650
}
@@ -4875,7 +4899,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
4875
4899
{
4876
4900
zend_string * field = NULL ;
4877
4901
zval meta , * def , * type , * not_null , * has_default , * is_enum , * val , new_val ;
4878
- int err = 0 ;
4902
+ int err = 0 , escape_err = 0 ;
4879
4903
bool skip_field ;
4880
4904
php_pgsql_data_type data_type ;
4881
4905
@@ -5121,8 +5145,13 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5121
5145
/* PostgreSQL ignores \0 */
5122
5146
str = zend_string_alloc (Z_STRLEN_P (val ) * 2 , 0 );
5123
5147
/* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */
5124
- ZSTR_LEN (str ) = PQescapeStringConn (pg_link , ZSTR_VAL (str ), Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5125
- ZVAL_STR (& new_val , php_pgsql_add_quotes (str ));
5148
+ ZSTR_LEN (str ) = PQescapeStringConn (pg_link , ZSTR_VAL (str ),
5149
+ Z_STRVAL_P (val ), Z_STRLEN_P (val ), & escape_err );
5150
+ if (escape_err ) {
5151
+ err = 1 ;
5152
+ } else {
5153
+ ZVAL_STR (& new_val , php_pgsql_add_quotes (str ));
5154
+ }
5126
5155
zend_string_release_ex (str , false);
5127
5156
}
5128
5157
break ;
@@ -5145,7 +5174,14 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5145
5174
}
5146
5175
PGSQL_CONV_CHECK_IGNORE ();
5147
5176
if (err ) {
5148
- 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 ));
5177
+ if (escape_err ) {
5178
+ php_error_docref (NULL , E_NOTICE ,
5179
+ "String value escaping failed for PostgreSQL '%s' (%s)" ,
5180
+ Z_STRVAL_P (type ), ZSTR_VAL (field ));
5181
+ } else {
5182
+ zend_type_error ("%s(): Field \"%s\" must be of type string|null, %s given" ,
5183
+ get_active_function_name (), ZSTR_VAL (field ), Z_STRVAL_P (type ));
5184
+ }
5149
5185
}
5150
5186
break ;
5151
5187
@@ -5379,6 +5415,11 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5379
5415
zend_string * tmp_zstr ;
5380
5416
5381
5417
tmp = PQescapeByteaConn (pg_link , (unsigned char * )Z_STRVAL_P (val ), Z_STRLEN_P (val ), & to_len );
5418
+ if (tmp == NULL ) {
5419
+ php_error_docref (NULL , E_NOTICE , "Escaping value failed for %s field (%s)" , Z_STRVAL_P (type ), ZSTR_VAL (field ));
5420
+ err = 1 ;
5421
+ break ;
5422
+ }
5382
5423
tmp_zstr = zend_string_init ((char * )tmp , to_len - 1 , false); /* PQescapeBytea's to_len includes additional '\0' */
5383
5424
PQfreemem (tmp );
5384
5425
@@ -5455,6 +5496,12 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
5455
5496
zend_hash_update (Z_ARRVAL_P (result ), field , & new_val );
5456
5497
} else {
5457
5498
char * escaped = PQescapeIdentifier (pg_link , ZSTR_VAL (field ), ZSTR_LEN (field ));
5499
+ if (escaped == NULL ) {
5500
+ /* This cannot fail because of invalid string but only due to failed memory allocation */
5501
+ php_error_docref (NULL , E_NOTICE , "Escaping field '%s' failed" , ZSTR_VAL (field ));
5502
+ err = 1 ;
5503
+ break ;
5504
+ }
5458
5505
add_assoc_zval (result , escaped , & new_val );
5459
5506
PQfreemem (escaped );
5460
5507
}
@@ -5537,7 +5584,7 @@ static bool do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link,
5537
5584
}
5538
5585
/* }}} */
5539
5586
5540
- static inline void build_tablename (smart_str * querystr , PGconn * pg_link , const zend_string * table ) /* {{{ */
5587
+ static inline zend_result build_tablename (smart_str * querystr , PGconn * pg_link , const zend_string * table ) /* {{{ */
5541
5588
{
5542
5589
/* schema.table should be "schema"."table" */
5543
5590
const char * dot = memchr (ZSTR_VAL (table ), '.' , ZSTR_LEN (table ));
@@ -5547,6 +5594,10 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z
5547
5594
smart_str_appendl (querystr , ZSTR_VAL (table ), len );
5548
5595
} else {
5549
5596
char * escaped = PQescapeIdentifier (pg_link , ZSTR_VAL (table ), len );
5597
+ if (escaped == NULL ) {
5598
+ php_error_docref (NULL , E_NOTICE , "Failed to escape table name '%s'" , ZSTR_VAL (table ));
5599
+ return FAILURE ;
5600
+ }
5550
5601
smart_str_appends (querystr , escaped );
5551
5602
PQfreemem (escaped );
5552
5603
}
@@ -5559,11 +5610,17 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z
5559
5610
smart_str_appendl (querystr , after_dot , len );
5560
5611
} else {
5561
5612
char * escaped = PQescapeIdentifier (pg_link , after_dot , len );
5613
+ if (escaped == NULL ) {
5614
+ php_error_docref (NULL , E_NOTICE , "Failed to escape table name '%s'" , ZSTR_VAL (table ));
5615
+ return FAILURE ;
5616
+ }
5562
5617
smart_str_appendc (querystr , '.' );
5563
5618
smart_str_appends (querystr , escaped );
5564
5619
PQfreemem (escaped );
5565
5620
}
5566
5621
}
5622
+
5623
+ return SUCCESS ;
5567
5624
}
5568
5625
/* }}} */
5569
5626
@@ -5584,7 +5641,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5584
5641
ZVAL_UNDEF (& converted );
5585
5642
if (zend_hash_num_elements (Z_ARRVAL_P (var_array )) == 0 ) {
5586
5643
smart_str_appends (& querystr , "INSERT INTO " );
5587
- build_tablename (& querystr , pg_link , table );
5644
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5645
+ goto cleanup ;
5646
+ }
5588
5647
smart_str_appends (& querystr , " DEFAULT VALUES" );
5589
5648
5590
5649
goto no_values ;
@@ -5600,7 +5659,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5600
5659
}
5601
5660
5602
5661
smart_str_appends (& querystr , "INSERT INTO " );
5603
- build_tablename (& querystr , pg_link , table );
5662
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5663
+ goto cleanup ;
5664
+ }
5604
5665
smart_str_appends (& querystr , " (" );
5605
5666
5606
5667
ZEND_HASH_FOREACH_STR_KEY (Z_ARRVAL_P (var_array ), fld ) {
@@ -5610,6 +5671,10 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5610
5671
}
5611
5672
if (opt & PGSQL_DML_ESCAPE ) {
5612
5673
tmp = PQescapeIdentifier (pg_link , ZSTR_VAL (fld ), ZSTR_LEN (fld ) + 1 );
5674
+ if (tmp == NULL ) {
5675
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s'" , ZSTR_VAL (fld ));
5676
+ goto cleanup ;
5677
+ }
5613
5678
smart_str_appends (& querystr , tmp );
5614
5679
PQfreemem (tmp );
5615
5680
} else {
@@ -5621,15 +5686,19 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t
5621
5686
smart_str_appends (& querystr , ") VALUES (" );
5622
5687
5623
5688
/* make values string */
5624
- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (var_array ), val ) {
5689
+ ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (var_array ), fld , val ) {
5625
5690
/* we can avoid the key_type check here, because we tested it in the other loop */
5626
5691
switch (Z_TYPE_P (val )) {
5627
5692
case IS_STRING :
5628
5693
if (opt & PGSQL_DML_ESCAPE ) {
5629
- size_t new_len ;
5630
- char * tmp ;
5631
- tmp = (char * )safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5632
- new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5694
+ int error ;
5695
+ char * tmp = safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5696
+ size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), & error );
5697
+ if (error ) {
5698
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s' value" , ZSTR_VAL (fld ));
5699
+ efree (tmp );
5700
+ goto cleanup ;
5701
+ }
5633
5702
smart_str_appendc (& querystr , '\'' );
5634
5703
smart_str_appendl (& querystr , tmp , new_len );
5635
5704
smart_str_appendc (& querystr , '\'' );
@@ -5787,6 +5856,10 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
5787
5856
}
5788
5857
if (opt & PGSQL_DML_ESCAPE ) {
5789
5858
char * tmp = PQescapeIdentifier (pg_link , ZSTR_VAL (fld ), ZSTR_LEN (fld ) + 1 );
5859
+ if (tmp == NULL ) {
5860
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s'" , ZSTR_VAL (fld ));
5861
+ return -1 ;
5862
+ }
5790
5863
smart_str_appends (querystr , tmp );
5791
5864
PQfreemem (tmp );
5792
5865
} else {
@@ -5802,8 +5875,14 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
5802
5875
switch (Z_TYPE_P (val )) {
5803
5876
case IS_STRING :
5804
5877
if (opt & PGSQL_DML_ESCAPE ) {
5878
+ int error ;
5805
5879
char * tmp = (char * )safe_emalloc (Z_STRLEN_P (val ), 2 , 1 );
5806
- size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), NULL );
5880
+ size_t new_len = PQescapeStringConn (pg_link , tmp , Z_STRVAL_P (val ), Z_STRLEN_P (val ), & error );
5881
+ if (error ) {
5882
+ php_error_docref (NULL , E_NOTICE , "Failed to escape field '%s' value" , ZSTR_VAL (fld ));
5883
+ efree (tmp );
5884
+ return -1 ;
5885
+ }
5807
5886
smart_str_appendc (querystr , '\'' );
5808
5887
smart_str_appendl (querystr , tmp , new_len );
5809
5888
smart_str_appendc (querystr , '\'' );
@@ -5871,7 +5950,9 @@ PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *t
5871
5950
}
5872
5951
5873
5952
smart_str_appends (& querystr , "UPDATE " );
5874
- build_tablename (& querystr , pg_link , table );
5953
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
5954
+ goto cleanup ;
5955
+ }
5875
5956
smart_str_appends (& querystr , " SET " );
5876
5957
5877
5958
if (build_assignment_string (pg_link , & querystr , Z_ARRVAL_P (var_array ), 0 , "," , 1 , opt ))
@@ -5977,7 +6058,9 @@ PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *t
5977
6058
}
5978
6059
5979
6060
smart_str_appends (& querystr , "DELETE FROM " );
5980
- build_tablename (& querystr , pg_link , table );
6061
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
6062
+ goto cleanup ;
6063
+ }
5981
6064
smart_str_appends (& querystr , " WHERE " );
5982
6065
5983
6066
if (build_assignment_string (pg_link , & querystr , Z_ARRVAL_P (ids_array ), 1 , " AND " , sizeof (" AND " )- 1 , opt ))
@@ -6121,7 +6204,9 @@ PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *t
6121
6204
}
6122
6205
6123
6206
smart_str_appends (& querystr , "SELECT * FROM " );
6124
- build_tablename (& querystr , pg_link , table );
6207
+ if (build_tablename (& querystr , pg_link , table ) == FAILURE ) {
6208
+ goto cleanup ;
6209
+ }
6125
6210
6126
6211
if (is_valid_ids_array ) {
6127
6212
smart_str_appends (& querystr , " WHERE " );
0 commit comments