@@ -295,7 +295,7 @@ static FbTokenType php_firebird_get_token(const char** begin, const char* end)
295295 return ret ;
296296}
297297
298- static int php_firebird_preprocess (const zend_string * sql , char * sql_out , HashTable * named_params )
298+ static int php_firebird_preprocess (const zend_string * sql , char * sql_out , size_t * sql_out_len , HashTable * named_params )
299299{
300300 bool passAsIs = 1 , execBlock = 0 ;
301301 zend_long pindex = -1 ;
@@ -326,7 +326,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
326326 if (l > 252 ) {
327327 return 0 ;
328328 }
329- strncpy (ident , i , l );
329+ memcpy (ident , i , l );
330330 ident [l ] = '\0' ;
331331 if (!strcasecmp (ident , "EXECUTE" ))
332332 {
@@ -351,7 +351,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
351351 if (l > 252 ) {
352352 return 0 ;
353353 }
354- strncpy (ident2 , i2 , l );
354+ memcpy (ident2 , i2 , l );
355355 ident2 [l ] = '\0' ;
356356 execBlock = !strcasecmp (ident2 , "BLOCK" );
357357 passAsIs = 0 ;
@@ -367,22 +367,28 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
367367
368368 if (passAsIs )
369369 {
370- strcpy (sql_out , ZSTR_VAL (sql ));
370+ memcpy (sql_out , ZSTR_VAL (sql ), ZSTR_LEN (sql ));
371+ sql_out [ZSTR_LEN (sql )] = '\0' ;
372+ * sql_out_len = ZSTR_LEN (sql );
371373 return 1 ;
372374 }
373375
374- strncat (sql_out , start , p - start );
376+ char * sql_out_p = sql_out ;
377+ memcpy (sql_out_p , start , p - start );
378+ sql_out_p += p - start ;
375379
376380 while (p < end )
377381 {
378382 start = p ;
379383 tok = php_firebird_get_token (& p , end );
380384 switch (tok )
381385 {
382- case ttParamMark :
383- tok = php_firebird_get_token (& p , end );
386+ case ttParamMark : {
387+ const char * p_peek = p ;
388+ tok = php_firebird_get_token (& p_peek , end );
384389 if (tok == ttIdent /*|| tok == ttString*/ )
385390 {
391+ p = p_peek ;
386392 ++ pindex ;
387393 l = p - start ;
388394 /* check the length of the identifier */
@@ -391,7 +397,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
391397 if (l > 253 ) {
392398 return 0 ;
393399 }
394- strncpy (pname , start , l );
400+ memcpy (pname , start , l );
395401 pname [l ] = '\0' ;
396402
397403 if (named_params ) {
@@ -400,7 +406,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
400406 zend_hash_str_update (named_params , pname , l , & tmp );
401407 }
402408
403- strcat ( sql_out , "?" ) ;
409+ * sql_out_p ++ = '?' ;
404410 }
405411 else
406412 {
@@ -410,10 +416,11 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
410416 return 0 ;
411417 }
412418 ++ pindex ;
413- strncat (sql_out , start , p - start );
419+ memcpy (sql_out_p , start , p - start );
420+ sql_out_p += p - start ;
414421 }
415422 break ;
416-
423+ }
417424 case ttIdent :
418425 if (execBlock )
419426 {
@@ -425,11 +432,14 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
425432 if (l > 252 ) {
426433 return 0 ;
427434 }
428- strncpy (ident , start , l );
435+ memcpy (ident , start , l );
429436 ident [l ] = '\0' ;
430437 if (!strcasecmp (ident , "AS" ))
431438 {
432- strncat (sql_out , start , end - start );
439+ memcpy (sql_out_p , start , end - start );
440+ sql_out_p += end - start ;
441+ * sql_out_p = '\0' ;
442+ * sql_out_len = sql_out_p - sql_out ;
433443 return 1 ;
434444 }
435445 }
@@ -440,7 +450,8 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
440450 case ttComment :
441451 case ttString :
442452 case ttOther :
443- strncat (sql_out , start , p - start );
453+ memcpy (sql_out_p , start , p - start );
454+ sql_out_p += p - start ;
444455 break ;
445456
446457 case ttBrokenComment :
@@ -458,6 +469,8 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
458469 break ;
459470 }
460471 }
472+ * sql_out_p = '\0' ;
473+ * sql_out_len = sql_out_p - sql_out ;
461474 return 1 ;
462475}
463476
@@ -792,7 +805,7 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
792805static zend_string * firebird_handle_quoter (pdo_dbh_t * dbh , const zend_string * unquoted , enum pdo_param_type paramtype )
793806{
794807 size_t qcount = 0 ;
795- char const * co , * l , * r ;
808+ char const * co , * l ;
796809 char * c ;
797810 size_t quotedlen ;
798811 zend_string * quoted_str ;
@@ -801,9 +814,15 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un
801814 return ZSTR_INIT_LITERAL ("''" , 0 );
802815 }
803816
817+ const char * const end = ZSTR_VAL (unquoted ) + ZSTR_LEN (unquoted );
818+
804819 /* Firebird only requires single quotes to be doubled if string lengths are used */
805820 /* count the number of ' characters */
806- for (co = ZSTR_VAL (unquoted ); (co = strchr (co ,'\'' )); qcount ++ , co ++ );
821+ for (co = ZSTR_VAL (unquoted ); co < end ; co ++ ) {
822+ if (* co == '\'' ) {
823+ qcount ++ ;
824+ }
825+ }
807826
808827 if (UNEXPECTED (ZSTR_LEN (unquoted ) + 2 > ZSTR_MAX_LEN - qcount )) {
809828 return NULL ;
@@ -815,15 +834,14 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un
815834 * c ++ = '\'' ;
816835
817836 /* foreach (chunk that ends in a quote) */
818- for (l = ZSTR_VAL (unquoted ); (r = strchr (l ,'\'' )); l = r + 1 ) {
819- strncpy (c , l , r - l + 1 );
820- c += (r - l + 1 );
821- /* add the second quote */
822- * c ++ = '\'' ;
837+ for (l = ZSTR_VAL (unquoted ); l < end ; l ++ ) {
838+ * c ++ = * l ;
839+ if (* l == '\'' ) {
840+ /* add the second quote */
841+ * c ++ = '\'' ;
842+ }
823843 }
824844
825- /* copy the remainder */
826- strncpy (c , l , quotedlen - (c - ZSTR_VAL (quoted_str ))- 1 );
827845 ZSTR_VAL (quoted_str )[quotedlen - 1 ] = '\'' ;
828846 ZSTR_VAL (quoted_str )[quotedlen ] = '\0' ;
829847
@@ -1001,6 +1019,7 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq
10011019{
10021020 pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
10031021 char * new_sql ;
1022+ size_t new_sql_len ;
10041023
10051024 /* allocate the statement */
10061025 if (isc_dsql_allocate_statement (H -> isc_status , & H -> db , s )) {
@@ -1012,14 +1031,14 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq
10121031 we need to replace :foo by ?, and store the name we just replaced */
10131032 new_sql = emalloc (ZSTR_LEN (sql )+ 1 );
10141033 new_sql [0 ] = '\0' ;
1015- if (!php_firebird_preprocess (sql , new_sql , named_params )) {
1034+ if (!php_firebird_preprocess (sql , new_sql , & new_sql_len , named_params )) {
10161035 php_firebird_error_with_info (dbh , "07000" , strlen ("07000" ), NULL , 0 );
10171036 efree (new_sql );
10181037 return 0 ;
10191038 }
10201039
10211040 /* prepare the statement */
1022- if (isc_dsql_prepare (H -> isc_status , & H -> tr , s , 0 , new_sql , H -> sql_dialect , out_sqlda )) {
1041+ if (isc_dsql_prepare (H -> isc_status , & H -> tr , s , new_sql_len , new_sql , H -> sql_dialect , out_sqlda )) {
10231042 php_firebird_error (dbh );
10241043 efree (new_sql );
10251044 return 0 ;
0 commit comments