@@ -262,9 +262,10 @@ static void dba_close(dba_info *info)
262262 if (info -> hnd ) {
263263 info -> hnd -> close (info );
264264 }
265- if (info -> path ) {
266- pefree (info -> path , info -> flags & DBA_PERSISTENT );
267- }
265+ ZEND_ASSERT (info -> path );
266+ zend_string_release_ex (info -> path , info -> flags & DBA_PERSISTENT );
267+ info -> path = NULL ;
268+
268269 if (info -> fp && info -> fp != info -> lock .fp ) {
269270 if (info -> flags & DBA_PERSISTENT ) {
270271 php_stream_pclose (info -> fp );
@@ -431,7 +432,7 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
431432/* }}} */
432433
433434/* {{{ php_find_dbm */
434- static dba_info * php_dba_find (const char * path )
435+ static dba_info * php_dba_find (const zend_string * path )
435436{
436437 zend_resource * le ;
437438 dba_info * info ;
@@ -444,7 +445,7 @@ static dba_info *php_dba_find(const char* path)
444445 }
445446 if (le -> type == le_db || le -> type == le_pdb ) {
446447 info = (dba_info * )(le -> ptr );
447- if (! strcmp ( info -> path , path )) {
448+ if (zend_string_equals ( path , info -> path )) {
448449 return (dba_info * )(le -> ptr );
449450 }
450451 }
@@ -454,6 +455,20 @@ static dba_info *php_dba_find(const char* path)
454455}
455456/* }}} */
456457
458+ static zend_always_inline zend_string * php_dba_zend_string_dup_safe (zend_string * s , bool persistent )
459+ {
460+ if (ZSTR_IS_INTERNED (s ) && !persistent ) {
461+ return s ;
462+ } else {
463+ zend_string * duplicated_str = zend_string_init (ZSTR_VAL (s ), ZSTR_LEN (s ), persistent );
464+ if (persistent ) {
465+ GC_MAKE_PERSISTENT_LOCAL (duplicated_str );
466+ }
467+ return duplicated_str ;
468+ }
469+ }
470+
471+
457472#define FREE_PERSISTENT_RESOURCE_KEY () if (persistent_resource_key) {zend_string_release_ex(persistent_resource_key, false);}
458473
459474/* {{{ php_dba_open */
@@ -467,7 +482,6 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
467482 const char * file_mode ;
468483 const char * lock_file_mode = NULL ;
469484 int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0 ;
470- zend_string * opened_path = NULL ;
471485 char * lock_name ;
472486#ifdef PHP_WIN32
473487 bool restarted = 0 ;
@@ -724,7 +738,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
724738
725739 info = pemalloc (sizeof (dba_info ), persistent );
726740 memset (info , 0 , sizeof (dba_info ));
727- info -> path = pestrdup ( ZSTR_VAL ( path ) , persistent );
741+ info -> path = php_dba_zend_string_dup_safe ( path , persistent );
728742 info -> mode = modenr ;
729743 info -> file_permission = permission ;
730744 info -> map_size = map_size ;
@@ -753,8 +767,9 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
753767 if (is_db_lock ) {
754768 lock_name = ZSTR_VAL (path );
755769 } else {
756- spprintf (& lock_name , 0 , "%s.lck" , info -> path );
770+ spprintf (& lock_name , 0 , "%s.lck" , ZSTR_VAL ( info -> path ) );
757771 if (!strcmp (file_mode , "r" )) {
772+ zend_string * opened_path = NULL ;
758773 /* when in read only mode try to use existing .lck file first */
759774 /* do not log errors for .lck file while in read only mode on .lck file */
760775 lock_file_mode = "rb" ;
@@ -769,13 +784,17 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
769784 }
770785 }
771786 if (!info -> lock .fp ) {
787+ zend_string * opened_path = NULL ;
772788 info -> lock .fp = php_stream_open_wrapper (lock_name , lock_file_mode , STREAM_MUST_SEEK |REPORT_ERRORS |IGNORE_PATH |persistent_flag , & opened_path );
773789 if (info -> lock .fp ) {
774790 if (is_db_lock ) {
791+ ZEND_ASSERT (opened_path );
775792 /* replace the path info with the real path of the opened file */
776- pefree (info -> path , persistent );
777- info -> path = pestrndup ( ZSTR_VAL ( opened_path ), ZSTR_LEN ( opened_path ) , persistent );
793+ zend_string_release (info -> path );
794+ info -> path = php_dba_zend_string_dup_safe ( opened_path , persistent );
778795 }
796+ }
797+ if (opened_path ) {
779798 zend_string_release_ex (opened_path , 0 );
780799 }
781800 }
@@ -801,7 +820,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
801820 if (info -> lock .fp && is_db_lock ) {
802821 info -> fp = info -> lock .fp ; /* use the same stream for locking and database access */
803822 } else {
804- info -> fp = php_stream_open_wrapper (info -> path , file_mode , STREAM_MUST_SEEK |REPORT_ERRORS |IGNORE_PATH |persistent_flag , NULL );
823+ info -> fp = php_stream_open_wrapper (ZSTR_VAL ( info -> path ) , file_mode , STREAM_MUST_SEEK |REPORT_ERRORS |IGNORE_PATH |persistent_flag , NULL );
805824 }
806825 if (!info -> fp ) {
807826 dba_close (info );
@@ -1207,7 +1226,7 @@ PHP_FUNCTION(dba_list)
12071226 }
12081227 if (le -> type == le_db || le -> type == le_pdb ) {
12091228 info = (dba_info * )(le -> ptr );
1210- add_index_string (return_value , i , info -> path );
1229+ add_index_str (return_value , i , zend_string_copy ( info -> path ) );
12111230 }
12121231 }
12131232}
0 commit comments