: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
|| ($p_filedescr_list[$j]['type'] == 'virtual_file')
|| ( ($p_filedescr_list[$j]['type'] == 'folder')
&& ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
|| !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
$v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
// ----- Store the file infos
$p_result_list[$v_nb++] = $v_header;
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privAddFile()
// --------------------------------------------------------------------------------
function privAddFile($p_filedescr, &$p_header, &$p_options)
// ----- Working variable
$p_filename = $p_filedescr['filename'];
// TBC : Already done in the fileAtt check ... ?
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
return PclZip::errorCode();
// ----- Look for a stored different filename
if (isset($p_filedescr['stored_filename'])) {
$v_stored_filename = $p_filedescr['stored_filename'];
$v_stored_filename = $p_filedescr['stored_filename'];
// ----- Set the file properties
$p_header['version'] = 20;
$p_header['version_extracted'] = 10;
$p_header['compression'] = 0;
$p_header['compressed_size'] = 0;
$p_header['filename_len'] = strlen($p_filename);
$p_header['extra_len'] = 0;
$p_header['internal'] = 0;
$p_header['filename'] = $p_filename;
// TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
$p_header['stored_filename'] = $p_filedescr['stored_filename'];
$p_header['status'] = 'ok';
// ----- Look for regular file
if ($p_filedescr['type']=='file') {
$p_header['external'] = 0x00000000;
$p_header['size'] = filesize($p_filename);
// ----- Look for regular folder
else if ($p_filedescr['type']=='folder') {
$p_header['external'] = 0x00000010;
$p_header['mtime'] = filemtime($p_filename);
$p_header['size'] = filesize($p_filename);
// ----- Look for virtual file
else if ($p_filedescr['type'] == 'virtual_file') {
$p_header['external'] = 0x00000000;
$p_header['size'] = strlen($p_filedescr['content']);
// ----- Look for filetime
if (isset($p_filedescr['mtime'])) {
$p_header['mtime'] = $p_filedescr['mtime'];
else if ($p_filedescr['type'] == 'virtual_file') {
$p_header['mtime'] = time();
$p_header['mtime'] = filemtime($p_filename);
// ------ Look for file comment
if (isset($p_filedescr['comment'])) {
$p_header['comment_len'] = strlen($p_filedescr['comment']);
$p_header['comment'] = $p_filedescr['comment'];
$p_header['comment_len'] = 0;
$p_header['comment'] = '';
// ----- Look for pre-add callback
if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
$v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
// ----- Change the file status
$p_header['status'] = "skipped";
// ----- Update the information
// Only some fields can be modified
if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
$p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
// ----- Look for empty stored filename
if ($p_header['stored_filename'] == "") {
$p_header['status'] = "filtered";
// ----- Check the path length
if (strlen($p_header['stored_filename']) > 0xFF) {
$p_header['status'] = 'filename_too_long';
// ----- Look if no error, or file not skipped
if ($p_header['status'] == 'ok') {
if ($p_filedescr['type'] == 'file') {
// ----- Look for using temporary file to zip
if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
&& (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
|| (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
&& ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
$v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
if ($v_result < PCLZIP_ERR_NO_ERROR) {
// ----- Use "in memory" zip algo
// ----- Open the source file
if (($v_file = @fopen($p_filename, "rb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
return PclZip::errorCode();
// ----- Read the file content
if ($p_header['size'] > 0) {
$v_content = @fread($v_file, $p_header['size']);
// ----- Calculate the CRC
$p_header['crc'] = @crc32($v_content);
// ----- Look for no compression
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
// ----- Set header parameters
$p_header['compressed_size'] = $p_header['size'];
$p_header['compression'] = 0;
// ----- Look for normal compression
// ----- Compress the content
$v_content = @gzdeflate($v_content);
// ----- Set header parameters
$p_header['compressed_size'] = strlen($v_content);
$p_header['compression'] = 8;
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
// ----- Write the compressed (or not) content
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
// ----- Look for a virtual file (a file from string)
else if ($p_filedescr['type'] == 'virtual_file') {
$v_content = $p_filedescr['content'];
// ----- Calculate the CRC
$p_header['crc'] = @crc32($v_content);
// ----- Look for no compression
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
// ----- Set header parameters
$p_header['compressed_size'] = $p_header['size'];
$p_header['compression'] = 0;
// ----- Look for normal compression
// ----- Compress the content
$v_content = @gzdeflate($v_content);
// ----- Set header parameters
$p_header['compressed_size'] = strlen($v_content);
$p_header['compression'] = 8;
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
// ----- Write the compressed (or not) content
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
// ----- Look for a directory
else if ($p_filedescr['type'] == 'folder') {
// ----- Look for directory last '/'
if (@substr($p_header['stored_filename'], -1) != '/') {
$p_header['stored_filename'] .= '/';
// ----- Set the file properties
//$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
$p_header['external'] = 0x00000010; // Value for a folder : to be checked
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
// ----- Look for post-add callback
if (isset($p_options[PCLZIP_CB_POST_ADD])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
$v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
// ----- Update the information
// Nothing can be modified
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privAddFileUsingTempFile()
// --------------------------------------------------------------------------------
function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
$v_result=PCLZIP_ERR_NO_ERROR;
// ----- Working variable
$p_filename = $p_filedescr['filename'];
// ----- Open the source file
if (($v_file = @fopen($p_filename, "rb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
return PclZip::errorCode();
// ----- Creates a compressed temporary file
$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
return PclZip::errorCode();
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
$v_size = filesize($p_filename);
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_file, $v_read_size);
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
@gzputs($v_file_compressed, $v_buffer, $v_read_size);
@gzclose($v_file_compressed);
// ----- Check the minimum file size
if (filesize($v_gzip_temp_name) < 18) {
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
return PclZip::errorCode();
// ----- Extract the compressed attributes
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
return PclZip::errorCode();
// ----- Read the gzip file header
$v_binary_data = @fread($v_file_compressed, 10);
$v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
// ----- Check some parameters
$v_data_header['os'] = bin2hex($v_data_header['os']);
// ----- Read the gzip file footer
@fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
$v_binary_data = @fread($v_file_compressed, 8);
$v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
// ----- Set the attributes
$p_header['compression'] = ord($v_data_header['cm']);
//$p_header['mtime'] = $v_data_header['mtime'];
$p_header['crc'] = $v_data_footer['crc'];
$p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
@fclose($v_file_compressed);
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
// ----- Add the compressed data
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
return PclZip::errorCode();
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
fseek($v_file_compressed, 10);
$v_size = $p_header['compressed_size'];
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_file_compressed, $v_read_size);
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
@fclose($v_file_compressed);
// ----- Unlink the temporary file
@unlink($v_gzip_temp_name);
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privCalculateStoredFilename()
// Based on file descriptor properties and global options, this method
// calculate the filename that will be stored in the archive.
// --------------------------------------------------------------------------------
function privCalculateStoredFilename(&$p_filedescr, &$p_options)
// ----- Working variables
$p_filename = $p_filedescr['filename'];
if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
$p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
$p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
$p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
// ----- Look for full name change
if (isset($p_filedescr['new_full_name'])) {
// ----- Remove drive letter if any
$v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
// ----- Look for path and/or short name change
// ----- Look for short name change
// Its when we change just the filename but not the path
if (isset($p_filedescr['new_short_name'])) {
$v_path_info = pathinfo($p_filename);
if ($v_path_info['dirname'] != '') {
$v_dir = $v_path_info['dirname'].'/';
$v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
// ----- Calculate the stored filename
$v_stored_filename = $p_filename;
// ----- Look for all path to remove
$v_stored_filename = basename($p_filename);
// ----- Look for partial path remove
else if ($p_remove_dir != "") {
if (substr($p_remove_dir, -1) != '/')
if ( (substr($p_filename, 0, 2) == "./")
|| (substr($p_remove_dir, 0, 2) == "./")) {
if ( (substr($p_filename, 0, 2) == "./")
&& (substr($p_remove_dir, 0, 2) != "./")) {
$p_remove_dir = "./".$p_remove_dir;
if ( (substr($p_filename, 0, 2) != "./")
&& (substr($p_remove_dir, 0, 2) == "./")) {
$p_remove_dir = substr($p_remove_dir, 2);
$v_compare = PclZipUtilPathInclusion($p_remove_dir,
$v_stored_filename = substr($v_stored_filename,