@@ -276,7 +276,11 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t
276
276
/* }}} */
277
277
278
278
static int php_zip_add_file (struct zip * za , const char * filename , size_t filename_len ,
279
- char * entry_name , size_t entry_name_len , long offset_start , long offset_len ) /* {{{ */
279
+ char * entry_name , size_t entry_name_len , /* unused if replace >= 0 */
280
+ zip_uint64_t offset_start , zip_uint64_t offset_len ,
281
+ zend_long replace , /* index to replace, add new file if < 0 */
282
+ zip_flags_t flags
283
+ ) /* {{{ */
280
284
{
281
285
struct zip_source * zs ;
282
286
char resolved_path [MAXPATHLEN ];
@@ -300,17 +304,30 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
300
304
if (!zs ) {
301
305
return -1 ;
302
306
}
303
- if (zip_file_add (za , entry_name , zs , ZIP_FL_OVERWRITE ) < 0 ) {
304
- zip_source_free (zs );
305
- return -1 ;
306
- } else {
307
+ // Replace
308
+ if (replace >= 0 ) {
309
+ if (zip_file_replace (za , replace , zs , flags ) < 0 ) {
310
+ zip_source_free (zs );
311
+ return -1 ;
312
+ }
307
313
zip_error_clear (za );
308
314
return 1 ;
309
315
}
316
+ // Add
317
+ if (zip_file_add (za , entry_name , zs , flags ) < 0 ) {
318
+ zip_source_free (zs );
319
+ return -1 ;
320
+ }
321
+ zip_error_clear (za );
322
+ return 1 ;
310
323
}
311
324
/* }}} */
312
325
313
- static int php_zip_parse_options (zval * options , zend_long * remove_all_path , char * * remove_path , size_t * remove_path_len , char * * add_path , size_t * add_path_len ) /* {{{ */
326
+ static int php_zip_parse_options (zval * options , zend_long * remove_all_path ,
327
+ char * * remove_path , size_t * remove_path_len ,
328
+ char * * add_path , size_t * add_path_len ,
329
+ zend_long * flags
330
+ ) /* {{{ */
314
331
{
315
332
zval * option ;
316
333
if ((option = zend_hash_str_find (Z_ARRVAL_P (options ), "remove_all_path" , sizeof ("remove_all_path" ) - 1 )) != NULL ) {
@@ -357,6 +374,15 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char
357
374
* add_path_len = Z_STRLEN_P (option );
358
375
* add_path = Z_STRVAL_P (option );
359
376
}
377
+
378
+ if ((option = zend_hash_str_find (Z_ARRVAL_P (options ), "flags" , sizeof ("flags" ) - 1 )) != NULL ) {
379
+ if (Z_TYPE_P (option ) != IS_LONG ) {
380
+ php_error_docref (NULL , E_WARNING , "flags option expected to be a integer" );
381
+ return -1 ;
382
+ }
383
+ * flags = Z_LVAL_P (option );
384
+ }
385
+
360
386
return 1 ;
361
387
}
362
388
/* }}} */
@@ -1545,7 +1571,7 @@ static ZIPARCHIVE_METHOD(getStatusString)
1545
1571
}
1546
1572
/* }}} */
1547
1573
1548
- /* {{{ proto bool ZipArchive::createEmptyDir (string dirname)
1574
+ /* {{{ proto bool ZipArchive::addEmptyDir (string dirname [, bool flags = 0] )
1549
1575
Returns the index of the entry named filename in the archive */
1550
1576
static ZIPARCHIVE_METHOD (addEmptyDir )
1551
1577
{
@@ -1556,11 +1582,12 @@ static ZIPARCHIVE_METHOD(addEmptyDir)
1556
1582
int idx ;
1557
1583
struct zip_stat sb ;
1558
1584
char * s ;
1585
+ zend_long flags = 0 ;
1559
1586
1560
1587
ZIP_FROM_OBJECT (intern , self );
1561
1588
1562
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "s" ,
1563
- & dirname , & dirname_len ) == FAILURE ) {
1589
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "s|l " ,
1590
+ & dirname , & dirname_len , & flags ) == FAILURE ) {
1564
1591
RETURN_THROWS ();
1565
1592
}
1566
1593
@@ -1581,7 +1608,7 @@ static ZIPARCHIVE_METHOD(addEmptyDir)
1581
1608
if (idx >= 0 ) {
1582
1609
RETVAL_FALSE ;
1583
1610
} else {
1584
- if (zip_dir_add (intern , (const char * )s , 0 ) == -1 ) {
1611
+ if (zip_dir_add (intern , (const char * )s , flags ) == -1 ) {
1585
1612
RETVAL_FALSE ;
1586
1613
} else {
1587
1614
zip_error_clear (intern );
@@ -1604,7 +1631,8 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
1604
1631
char * add_path = NULL ;
1605
1632
size_t add_path_len , remove_path_len = 0 , path_len = 1 ;
1606
1633
zend_long remove_all_path = 0 ;
1607
- zend_long flags = 0 ;
1634
+ zend_long glob_flags = 0 ;
1635
+ zend_long zip_flags = ZIP_FL_OVERWRITE ;
1608
1636
zval * options = NULL ;
1609
1637
int found ;
1610
1638
zend_string * pattern ;
@@ -1613,7 +1641,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
1613
1641
/* 1 == glob, 2 == pcre */
1614
1642
if (type == 1 ) {
1615
1643
if (zend_parse_parameters (ZEND_NUM_ARGS (), "P|la" ,
1616
- & pattern , & flags , & options ) == FAILURE ) {
1644
+ & pattern , & glob_flags , & options ) == FAILURE ) {
1617
1645
RETURN_THROWS ();
1618
1646
}
1619
1647
} else {
@@ -1628,7 +1656,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
1628
1656
RETURN_FALSE ;
1629
1657
}
1630
1658
if (options && (php_zip_parse_options (options , & remove_all_path , & remove_path , & remove_path_len ,
1631
- & add_path , & add_path_len ) < 0 )) {
1659
+ & add_path , & add_path_len , & zip_flags ) < 0 )) {
1632
1660
RETURN_FALSE ;
1633
1661
}
1634
1662
@@ -1642,7 +1670,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
1642
1670
}
1643
1671
1644
1672
if (type == 1 ) {
1645
- found = php_zip_glob (ZSTR_VAL (pattern ), ZSTR_LEN (pattern ), flags , return_value );
1673
+ found = php_zip_glob (ZSTR_VAL (pattern ), ZSTR_LEN (pattern ), glob_flags , return_value );
1646
1674
} else {
1647
1675
found = php_zip_pcre (pattern , path , path_len , return_value );
1648
1676
}
@@ -1690,7 +1718,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
1690
1718
}
1691
1719
1692
1720
if (php_zip_add_file (intern , Z_STRVAL_P (zval_file ), Z_STRLEN_P (zval_file ),
1693
- entry_name , entry_name_len , 0 , 0 ) < 0 ) {
1721
+ entry_name , entry_name_len , 0 , 0 , -1 , zip_flags ) < 0 ) {
1694
1722
zend_array_destroy (Z_ARR_P (return_value ));
1695
1723
RETURN_FALSE ;
1696
1724
}
@@ -1719,7 +1747,7 @@ static ZIPARCHIVE_METHOD(addPattern)
1719
1747
}
1720
1748
/* }}} */
1721
1749
1722
- /* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
1750
+ /* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length [, int flags = FL_OVERWRITE] ]]])
1723
1751
Add a file in a Zip archive using its path and the name to use. */
1724
1752
static ZIPARCHIVE_METHOD (addFile )
1725
1753
{
@@ -1729,11 +1757,12 @@ static ZIPARCHIVE_METHOD(addFile)
1729
1757
size_t entry_name_len = 0 ;
1730
1758
zend_long offset_start = 0 , offset_len = 0 ;
1731
1759
zend_string * filename ;
1760
+ zend_long flags = ZIP_FL_OVERWRITE ;
1732
1761
1733
1762
ZIP_FROM_OBJECT (intern , self );
1734
1763
1735
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "P|sll " ,
1736
- & filename , & entry_name , & entry_name_len , & offset_start , & offset_len ) == FAILURE ) {
1764
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "P|slll " ,
1765
+ & filename , & entry_name , & entry_name_len , & offset_start , & offset_len , & flags ) == FAILURE ) {
1737
1766
RETURN_THROWS ();
1738
1767
}
1739
1768
@@ -1748,15 +1777,52 @@ static ZIPARCHIVE_METHOD(addFile)
1748
1777
}
1749
1778
1750
1779
if (php_zip_add_file (intern , ZSTR_VAL (filename ), ZSTR_LEN (filename ),
1751
- entry_name , entry_name_len , offset_start , offset_len ) < 0 ) {
1780
+ entry_name , entry_name_len , offset_start , offset_len , -1 , flags ) < 0 ) {
1781
+ RETURN_FALSE ;
1782
+ } else {
1783
+ RETURN_TRUE ;
1784
+ }
1785
+ }
1786
+ /* }}} */
1787
+
1788
+ /* {{{ proto bool ZipArchive::replaceFile(string filepath, int index[, int start [, int length [, int flags = 0]]])
1789
+ Add a file in a Zip archive using its path and the name to use. */
1790
+ static ZIPARCHIVE_METHOD (replaceFile )
1791
+ {
1792
+ struct zip * intern ;
1793
+ zval * self = ZEND_THIS ;
1794
+ zend_long index ;
1795
+ zend_long offset_start = 0 , offset_len = 0 ;
1796
+ zend_string * filename ;
1797
+ zend_long flags = ZIP_FL_OVERWRITE ;
1798
+
1799
+ ZIP_FROM_OBJECT (intern , self );
1800
+
1801
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "Pl|lll" ,
1802
+ & filename , & index , & offset_start , & offset_len , & flags ) == FAILURE ) {
1803
+ RETURN_THROWS ();
1804
+ }
1805
+
1806
+ if (ZSTR_LEN (filename ) == 0 ) {
1807
+ php_error_docref (NULL , E_NOTICE , "Empty string as filename" );
1808
+ RETURN_FALSE ;
1809
+ }
1810
+
1811
+ if (index < 0 ) {
1812
+ php_error_docref (NULL , E_NOTICE , "Invalid negative index" );
1813
+ RETURN_FALSE ;
1814
+ }
1815
+
1816
+ if (php_zip_add_file (intern , ZSTR_VAL (filename ), ZSTR_LEN (filename ),
1817
+ NULL , 0 , offset_start , offset_len , index , flags ) < 0 ) {
1752
1818
RETURN_FALSE ;
1753
1819
} else {
1754
1820
RETURN_TRUE ;
1755
1821
}
1756
1822
}
1757
1823
/* }}} */
1758
1824
1759
- /* {{{ proto bool ZipArchive::addFromString(string name, string content)
1825
+ /* {{{ proto bool ZipArchive::addFromString(string name, string content [, int flags = FL_OVERWRITE] )
1760
1826
Add a file using content and the entry name */
1761
1827
static ZIPARCHIVE_METHOD (addFromString )
1762
1828
{
@@ -1768,12 +1834,12 @@ static ZIPARCHIVE_METHOD(addFromString)
1768
1834
ze_zip_object * ze_obj ;
1769
1835
struct zip_source * zs ;
1770
1836
int pos = 0 ;
1771
- int cur_idx ;
1837
+ zend_long flags = ZIP_FL_OVERWRITE ;
1772
1838
1773
1839
ZIP_FROM_OBJECT (intern , self );
1774
1840
1775
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "sS" ,
1776
- & name , & name_len , & buffer ) == FAILURE ) {
1841
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "sS|l " ,
1842
+ & name , & name_len , & buffer , & flags ) == FAILURE ) {
1777
1843
RETURN_THROWS ();
1778
1844
}
1779
1845
@@ -1795,16 +1861,7 @@ static ZIPARCHIVE_METHOD(addFromString)
1795
1861
RETURN_FALSE ;
1796
1862
}
1797
1863
1798
- cur_idx = zip_name_locate (intern , (const char * )name , 0 );
1799
- /* TODO: fix _zip_replace */
1800
- if (cur_idx >= 0 ) {
1801
- if (zip_delete (intern , cur_idx ) == -1 ) {
1802
- zip_source_free (zs );
1803
- RETURN_FALSE ;
1804
- }
1805
- }
1806
-
1807
- if (zip_file_add (intern , name , zs , 0 ) == -1 ) {
1864
+ if (zip_file_add (intern , name , zs , flags ) == -1 ) {
1808
1865
zip_source_free (zs );
1809
1866
RETURN_FALSE ;
1810
1867
} else {
@@ -2939,6 +2996,7 @@ static const zend_function_entry zip_class_functions[] = {
2939
2996
ZIPARCHIVE_ME (addPattern , arginfo_class_ZipArchive_addPattern , ZEND_ACC_PUBLIC )
2940
2997
ZIPARCHIVE_ME (renameIndex , arginfo_class_ZipArchive_renameIndex , ZEND_ACC_PUBLIC )
2941
2998
ZIPARCHIVE_ME (renameName , arginfo_class_ZipArchive_renameName , ZEND_ACC_PUBLIC )
2999
+ ZIPARCHIVE_ME (replaceFile , arginfo_class_ZipArchive_replaceFile , ZEND_ACC_PUBLIC )
2942
3000
ZIPARCHIVE_ME (setArchiveComment , arginfo_class_ZipArchive_setArchiveComment , ZEND_ACC_PUBLIC )
2943
3001
ZIPARCHIVE_ME (getArchiveComment , arginfo_class_ZipArchive_getArchiveComment , ZEND_ACC_PUBLIC )
2944
3002
ZIPARCHIVE_ME (setCommentIndex , arginfo_class_ZipArchive_setCommentIndex , ZEND_ACC_PUBLIC )
@@ -3030,23 +3088,18 @@ static PHP_MINIT_FUNCTION(zip)
3030
3088
REGISTER_ZIP_CLASS_CONST_LONG ("FL_NODIR" , ZIP_FL_NODIR );
3031
3089
REGISTER_ZIP_CLASS_CONST_LONG ("FL_COMPRESSED" , ZIP_FL_COMPRESSED );
3032
3090
REGISTER_ZIP_CLASS_CONST_LONG ("FL_UNCHANGED" , ZIP_FL_UNCHANGED );
3091
+ REGISTER_ZIP_CLASS_CONST_LONG ("FL_RECOMPRESS" , ZIP_FL_RECOMPRESS );
3092
+ REGISTER_ZIP_CLASS_CONST_LONG ("FL_ENCRYPTED" , ZIP_FL_ENCRYPTED );
3093
+ REGISTER_ZIP_CLASS_CONST_LONG ("FL_OVERWRITE" , ZIP_FL_OVERWRITE );
3094
+ REGISTER_ZIP_CLASS_CONST_LONG ("FL_LOCAL" , ZIP_FL_LOCAL );
3095
+ REGISTER_ZIP_CLASS_CONST_LONG ("FL_CENTRAL" , ZIP_FL_CENTRAL );
3033
3096
3034
- #ifdef ZIP_FL_ENC_GUESS
3035
3097
/* Default filename encoding policy. */
3036
3098
REGISTER_ZIP_CLASS_CONST_LONG ("FL_ENC_GUESS" , ZIP_FL_ENC_GUESS );
3037
- #endif
3038
- #ifdef ZIP_FL_ENC_RAW
3039
3099
REGISTER_ZIP_CLASS_CONST_LONG ("FL_ENC_RAW" , ZIP_FL_ENC_RAW );
3040
- #endif
3041
- #ifdef ZIP_FL_ENC_STRICT
3042
3100
REGISTER_ZIP_CLASS_CONST_LONG ("FL_ENC_STRICT" , ZIP_FL_ENC_STRICT );
3043
- #endif
3044
- #ifdef ZIP_FL_ENC_UTF_8
3045
3101
REGISTER_ZIP_CLASS_CONST_LONG ("FL_ENC_UTF_8" , ZIP_FL_ENC_UTF_8 );
3046
- #endif
3047
- #ifdef ZIP_FL_ENC_CP437
3048
3102
REGISTER_ZIP_CLASS_CONST_LONG ("FL_ENC_CP437" , ZIP_FL_ENC_CP437 );
3049
- #endif
3050
3103
3051
3104
REGISTER_ZIP_CLASS_CONST_LONG ("CM_DEFAULT" , ZIP_CM_DEFAULT );
3052
3105
REGISTER_ZIP_CLASS_CONST_LONG ("CM_STORE" , ZIP_CM_STORE );
0 commit comments