Test Setup Failed
Push — master ( 0ccb08...acf878 )
by Bingo
03:37
created

PclZip   F

Complexity

Total Complexity 602

Size/Duplication

Total Lines 4934
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1845
c 1
b 0
f 0
dl 0
loc 4934
rs 0.8
wmc 602

50 Methods

Rating   Name   Duplication   Size   Complexity  
A privErrorReset() 0 7 2
F privDeleteByRule() 0 276 43
A delete() 0 52 5
A privCreate() 0 25 2
B privReadFileHeader() 0 88 6
A errorName() 0 37 3
A errorCode() 0 7 2
F privExtractFile() 0 302 49
D extractByIndex() 0 129 17
A privErrorLog() 0 7 2
C privReadEndCentralDir() 0 140 15
A privCheckFormat() 0 37 3
A privCloseFd() 0 11 2
B privAddFileUsingTempFile() 0 103 11
B privAddList() 0 49 7
B privOptionDefaultThreshold() 0 35 7
B privExtractFileUsingTempFile() 0 67 8
F privParseOptions() 0 377 63
A privSwapBackMagicQuotes() 0 21 5
A properties() 0 57 5
A privOpenFd() 0 24 3
A deleteByIndex() 0 7 1
D privMerge() 0 165 17
C privAddFileList() 0 45 12
D add() 0 138 17
B privList() 0 62 6
B privDirCheck() 0 38 9
B privReadCentralFileHeader() 0 94 8
F privAdd() 0 163 18
A __construct() 0 15 2
A privDuplicate() 0 48 6
C extract() 0 114 15
A errorInfo() 0 11 3
A privWriteFileHeader() 0 28 3
A merge() 0 36 5
A privWriteCentralHeader() 0 17 2
F privCalculateStoredFilename() 0 93 20
A privDisableMagicQuotes() 0 24 5
C privExtractFileInOutput() 0 100 12
C privFileDescrExpand() 0 107 17
C privExtractFileAsString() 0 108 13
F privExtractByRule() 0 297 60
D create() 0 137 18
A duplicate() 0 36 5
A privConvertHeader2FileInfo() 0 20 1
F privAddFile() 0 250 31
B privCheckFileHeaders() 0 28 8
A privWriteCentralFileHeader() 0 32 4
A listContent() 0 22 3
D privFileDescrParseAtt() 0 120 21

How to fix   Complexity   

Complex Class

Complex classes like PclZip often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PclZip, and based on these observations, apply Extract Interface, too.

1
<?php
2
// --------------------------------------------------------------------------------
3
// PhpConcept Library - Zip Module 2.8.2
4
// --------------------------------------------------------------------------------
5
// License GNU/LGPL - Vincent Blavet - August 2009
6
// http://www.phpconcept.net
7
// --------------------------------------------------------------------------------
8
//
9
// Presentation :
10
//   PclZip is a PHP library that manage ZIP archives.
11
//   So far tests show that archives generated by PclZip are readable by
12
//   WinZip application and other tools.
13
//
14
// Description :
15
//   See readme.txt and http://www.phpconcept.net
16
//
17
// Warning :
18
//   This library and the associated files are non commercial, non professional
19
//   work.
20
//   It should not have unexpected results. However if any damage is caused by
21
//   this software the author can not be responsible.
22
//   The use of this software is at the risk of the user.
23
//
24
// --------------------------------------------------------------------------------
25
// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
26
// --------------------------------------------------------------------------------
27
28
// ----- Constants
29
if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
30
    define('PCLZIP_READ_BLOCK_SIZE', 2048);
31
}
32
33
// ----- File list separator
34
// In version 1.x of PclZip, the separator for file list is a space
35
// (which is not a very smart choice, specifically for windows paths !).
36
// A better separator should be a comma (,). This constant gives you the
37
// abilty to change that.
38
// However notice that changing this value, may have impact on existing
39
// scripts, using space separated filenames.
40
// Recommanded values for compatibility with older versions :
41
//define( 'PCLZIP_SEPARATOR', ' ' );
42
// Recommanded values for smart separation of filenames.
43
if (!defined('PCLZIP_SEPARATOR')) {
44
    define('PCLZIP_SEPARATOR', ',');
45
}
46
47
// ----- Error configuration
48
// 0 : PclZip Class integrated error handling
49
// 1 : PclError external library error handling. By enabling this
50
//     you must ensure that you have included PclError library.
51
// [2,...] : reserved for futur use
52
if (!defined('PCLZIP_ERROR_EXTERNAL')) {
53
    define('PCLZIP_ERROR_EXTERNAL', 0);
54
}
55
56
// ----- Optional static temporary directory
57
//       By default temporary files are generated in the script current
58
//       path.
59
//       If defined :
60
//       - MUST BE terminated by a '/'.
61
//       - MUST be a valid, already created directory
62
//       Samples :
63
// define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
64
// define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
65
if (!defined('PCLZIP_TEMPORARY_DIR')) {
66
    define('PCLZIP_TEMPORARY_DIR', '');
67
}
68
69
// ----- Optional threshold ratio for use of temporary files
70
//       Pclzip sense the size of the file to add/extract and decide to
71
//       use or not temporary file. The algorythm is looking for
72
//       memory_limit of PHP and apply a ratio.
73
//       threshold = memory_limit * ratio.
74
//       Recommended values are under 0.5. Default 0.47.
75
//       Samples :
76
// define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
77
if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
78
    define('PCLZIP_TEMPORARY_FILE_RATIO', 0.47);
79
}
80
81
// --------------------------------------------------------------------------------
82
// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
83
// --------------------------------------------------------------------------------
84
85
// ----- Global variables
86
$g_pclzip_version = "2.8.2";
87
88
// ----- Error codes
89
//   -1 : Unable to open file in binary write mode
90
//   -2 : Unable to open file in binary read mode
91
//   -3 : Invalid parameters
92
//   -4 : File does not exist
93
//   -5 : Filename is too long (max. 255)
94
//   -6 : Not a valid zip file
95
//   -7 : Invalid extracted file size
96
//   -8 : Unable to create directory
97
//   -9 : Invalid archive extension
98
//  -10 : Invalid archive format
99
//  -11 : Unable to delete file (unlink)
100
//  -12 : Unable to rename file (rename)
101
//  -13 : Invalid header checksum
102
//  -14 : Invalid archive size
103
define('PCLZIP_ERR_USER_ABORTED', 2);
104
define('PCLZIP_ERR_NO_ERROR', 0);
105
define('PCLZIP_ERR_WRITE_OPEN_FAIL', -1);
106
define('PCLZIP_ERR_READ_OPEN_FAIL', -2);
107
define('PCLZIP_ERR_INVALID_PARAMETER', -3);
108
define('PCLZIP_ERR_MISSING_FILE', -4);
109
define('PCLZIP_ERR_FILENAME_TOO_LONG', -5);
110
define('PCLZIP_ERR_INVALID_ZIP', -6);
111
define('PCLZIP_ERR_BAD_EXTRACTED_FILE', -7);
112
define('PCLZIP_ERR_DIR_CREATE_FAIL', -8);
113
define('PCLZIP_ERR_BAD_EXTENSION', -9);
114
define('PCLZIP_ERR_BAD_FORMAT', -10);
115
define('PCLZIP_ERR_DELETE_FILE_FAIL', -11);
116
define('PCLZIP_ERR_RENAME_FILE_FAIL', -12);
117
define('PCLZIP_ERR_BAD_CHECKSUM', -13);
118
define('PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14);
119
define('PCLZIP_ERR_MISSING_OPTION_VALUE', -15);
120
define('PCLZIP_ERR_INVALID_OPTION_VALUE', -16);
121
define('PCLZIP_ERR_ALREADY_A_DIRECTORY', -17);
122
define('PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18);
123
define('PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19);
124
define('PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20);
125
define('PCLZIP_ERR_DIRECTORY_RESTRICTION', -21);
126
127
// ----- Options values
128
define('PCLZIP_OPT_PATH', 77001);
129
define('PCLZIP_OPT_ADD_PATH', 77002);
130
define('PCLZIP_OPT_REMOVE_PATH', 77003);
131
define('PCLZIP_OPT_REMOVE_ALL_PATH', 77004);
132
define('PCLZIP_OPT_SET_CHMOD', 77005);
133
define('PCLZIP_OPT_EXTRACT_AS_STRING', 77006);
134
define('PCLZIP_OPT_NO_COMPRESSION', 77007);
135
define('PCLZIP_OPT_BY_NAME', 77008);
136
define('PCLZIP_OPT_BY_INDEX', 77009);
137
define('PCLZIP_OPT_BY_EREG', 77010);
138
define('PCLZIP_OPT_BY_PREG', 77011);
139
define('PCLZIP_OPT_COMMENT', 77012);
140
define('PCLZIP_OPT_ADD_COMMENT', 77013);
141
define('PCLZIP_OPT_PREPEND_COMMENT', 77014);
142
define('PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015);
143
define('PCLZIP_OPT_REPLACE_NEWER', 77016);
144
define('PCLZIP_OPT_STOP_ON_ERROR', 77017);
145
// Having big trouble with crypt. Need to multiply 2 long int
146
// which is not correctly supported by PHP ...
147
//define( 'PCLZIP_OPT_CRYPT', 77018 );
148
define('PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019);
149
define('PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020);
150
define('PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020); // alias
151
define('PCLZIP_OPT_TEMP_FILE_ON', 77021);
152
define('PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021); // alias
153
define('PCLZIP_OPT_TEMP_FILE_OFF', 77022);
154
define('PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022); // alias
155
156
// ----- File description attributes
157
define('PCLZIP_ATT_FILE_NAME', 79001);
158
define('PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002);
159
define('PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003);
160
define('PCLZIP_ATT_FILE_MTIME', 79004);
161
define('PCLZIP_ATT_FILE_CONTENT', 79005);
162
define('PCLZIP_ATT_FILE_COMMENT', 79006);
163
164
// ----- Call backs values
165
define('PCLZIP_CB_PRE_EXTRACT', 78001);
166
define('PCLZIP_CB_POST_EXTRACT', 78002);
167
define('PCLZIP_CB_PRE_ADD', 78003);
168
define('PCLZIP_CB_POST_ADD', 78004);
169
/* For futur use
170
define( 'PCLZIP_CB_PRE_LIST', 78005 );
171
define( 'PCLZIP_CB_POST_LIST', 78006 );
172
define( 'PCLZIP_CB_PRE_DELETE', 78007 );
173
define( 'PCLZIP_CB_POST_DELETE', 78008 );
174
*/
175
176
// --------------------------------------------------------------------------------
177
// Class : PclZip
178
// Description :
179
//   PclZip is the class that represent a Zip archive.
180
//   The public methods allow the manipulation of the archive.
181
// Attributes :
182
//   Attributes must not be accessed directly.
183
// Methods :
184
//   PclZip() : Object creator
185
//   create() : Creates the Zip archive
186
//   listContent() : List the content of the Zip archive
187
//   extract() : Extract the content of the archive
188
//   properties() : List the properties of the archive
189
// --------------------------------------------------------------------------------
190
class PclZip
191
{
192
    // ----- Filename of the zip file
193
    public $zipname = '';
194
195
    // ----- File descriptor of the zip file
196
    public $zip_fd = 0;
197
198
    // ----- Internal error handling
199
    public $error_code = 1;
200
    public $error_string = '';
201
202
    // ----- Current status of the magic_quotes_runtime
203
    // This value store the php configuration for magic_quotes
204
    // The class can then disable the magic_quotes and reset it after
205
    public $magic_quotes_status;
206
207
    // --------------------------------------------------------------------------------
208
    // Function : PclZip()
209
    // Description :
210
    //   Creates a PclZip object and set the name of the associated Zip archive
211
    //   filename.
212
    //   Note that no real action is taken, if the archive does not exist it is not
213
    //   created. Use create() for that.
214
    // --------------------------------------------------------------------------------
215
    public function __construct($p_zipname)
216
    {
217
218
        // ----- Tests the zlib
219
        if (!function_exists('gzopen')) {
220
            die('Abort ' . basename(__FILE__) . ' : Missing zlib extensions');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
221
        }
222
223
        // ----- Set the attributes
224
        $this->zipname             = $p_zipname;
225
        $this->zip_fd              = 0;
226
        $this->magic_quotes_status = -1;
227
228
        // ----- Return
229
        return;
230
    }
231
    // --------------------------------------------------------------------------------
232
233
    // --------------------------------------------------------------------------------
234
    // Function :
235
    //   create($p_filelist, $p_add_dir="", $p_remove_dir="")
236
    //   create($p_filelist, $p_option, $p_option_value, ...)
237
    // Description :
238
    //   This method supports two different synopsis. The first one is historical.
239
    //   This method creates a Zip Archive. The Zip file is created in the
240
    //   filesystem. The files and directories indicated in $p_filelist
241
    //   are added in the archive. See the parameters description for the
242
    //   supported format of $p_filelist.
243
    //   When a directory is in the list, the directory and its content is added
244
    //   in the archive.
245
    //   In this synopsis, the function takes an optional variable list of
246
    //   options. See bellow the supported options.
247
    // Parameters :
248
    //   $p_filelist : An array containing file or directory names, or
249
    //                 a string containing one filename or one directory name, or
250
    //                 a string containing a list of filenames and/or directory
251
    //                 names separated by spaces.
252
    //   $p_add_dir : A path to add before the real path of the archived file,
253
    //                in order to have it memorized in the archive.
254
    //   $p_remove_dir : A path to remove from the real path of the file to archive,
255
    //                   in order to have a shorter path memorized in the archive.
256
    //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
257
    //                   is removed first, before $p_add_dir is added.
258
    // Options :
259
    //   PCLZIP_OPT_ADD_PATH :
260
    //   PCLZIP_OPT_REMOVE_PATH :
261
    //   PCLZIP_OPT_REMOVE_ALL_PATH :
262
    //   PCLZIP_OPT_COMMENT :
263
    //   PCLZIP_CB_PRE_ADD :
264
    //   PCLZIP_CB_POST_ADD :
265
    // Return Values :
266
    //   0 on failure,
267
    //   The list of the added files, with a status of the add action.
268
    //   (see PclZip::listContent() for list entry format)
269
    // --------------------------------------------------------------------------------
270
    public function create($p_filelist)
271
    {
272
        $v_result = 1;
273
274
        // ----- Reset the error handler
275
        $this->privErrorReset();
276
277
        // ----- Set default values
278
        $v_options                            = array();
279
        $v_options[PCLZIP_OPT_NO_COMPRESSION] = false;
280
281
        // ----- Look for variable options arguments
282
        $v_size = func_num_args();
283
284
        // ----- Look for arguments
285
        if ($v_size > 1) {
286
            // ----- Get the arguments
287
            $v_arg_list = func_get_args();
288
289
            // ----- Remove from the options list the first argument
290
            array_shift($v_arg_list);
291
            $v_size--;
292
293
            // ----- Look for first arg
294
            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
295
296
                // ----- Parse the options
297
                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
298
                    PCLZIP_OPT_REMOVE_PATH => 'optional',
299
                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
300
                    PCLZIP_OPT_ADD_PATH => 'optional',
301
                    PCLZIP_CB_PRE_ADD => 'optional',
302
                    PCLZIP_CB_POST_ADD => 'optional',
303
                    PCLZIP_OPT_NO_COMPRESSION => 'optional',
304
                    PCLZIP_OPT_COMMENT => 'optional',
305
                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
306
                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
307
                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
308
                    //, PCLZIP_OPT_CRYPT => 'optional'
309
                ));
310
                if ($v_result != 1) {
311
                    return 0;
312
                }
313
314
            // ----- Look for 2 args
315
            // Here we need to support the first historic synopsis of the
316
            // method.
317
            } else {
318
319
                // ----- Get the first argument
320
                $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
321
322
                // ----- Look for the optional second argument
323
                if ($v_size == 2) {
324
                    $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
325
                } elseif ($v_size > 2) {
326
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

326
                    PclZip::/** @scrutinizer ignore-call */ 
327
                            privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
Loading history...
327
328
                    return 0;
329
                }
330
            }
331
        }
332
333
        // ----- Look for default option values
334
        $this->privOptionDefaultThreshold($v_options);
335
336
        // ----- Init
337
        $v_string_list    = array();
338
        $v_att_list       = array();
339
        $v_filedescr_list = array();
340
        $p_result_list    = array();
341
342
        // ----- Look if the $p_filelist is really an array
343
        if (is_array($p_filelist)) {
344
345
            // ----- Look if the first element is also an array
346
            //       This will mean that this is a file description entry
347
            if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
348
                $v_att_list = $p_filelist;
349
350
            // ----- The list is a list of string names
351
            } else {
352
                $v_string_list = $p_filelist;
353
            }
354
355
        // ----- Look if the $p_filelist is a string
356
        } elseif (is_string($p_filelist)) {
357
            // ----- Create a list from the string
358
            $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
359
360
        // ----- Invalid variable type for $p_filelist
361
        } else {
362
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
363
364
            return 0;
365
        }
366
367
        // ----- Reformat the string list
368
        if (sizeof($v_string_list) != 0) {
369
            foreach ($v_string_list as $v_string) {
370
                if ($v_string != '') {
371
                    $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
372
                } else {
373
                }
374
            }
375
        }
376
377
        // ----- For each file in the list check the attributes
378
        $v_supported_attributes = array(
379
            PCLZIP_ATT_FILE_NAME => 'mandatory',
380
            PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional',
381
            PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional',
382
            PCLZIP_ATT_FILE_MTIME => 'optional',
383
            PCLZIP_ATT_FILE_CONTENT => 'optional',
384
            PCLZIP_ATT_FILE_COMMENT => 'optional'
385
        );
386
        foreach ($v_att_list as $v_entry) {
387
            $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes);
388
            if ($v_result != 1) {
389
                return 0;
390
            }
391
        }
392
393
        // ----- Expand the filelist (expand directories)
394
        $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
395
        if ($v_result != 1) {
396
            return 0;
397
        }
398
399
        // ----- Call the create fct
400
        $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
401
        if ($v_result != 1) {
402
            return 0;
403
        }
404
405
        // ----- Return
406
        return $p_result_list;
407
    }
408
    // --------------------------------------------------------------------------------
409
410
    // --------------------------------------------------------------------------------
411
    // Function :
412
    //   add($p_filelist, $p_add_dir="", $p_remove_dir="")
413
    //   add($p_filelist, $p_option, $p_option_value, ...)
414
    // Description :
415
    //   This method supports two synopsis. The first one is historical.
416
    //   This methods add the list of files in an existing archive.
417
    //   If a file with the same name already exists, it is added at the end of the
418
    //   archive, the first one is still present.
419
    //   If the archive does not exist, it is created.
420
    // Parameters :
421
    //   $p_filelist : An array containing file or directory names, or
422
    //                 a string containing one filename or one directory name, or
423
    //                 a string containing a list of filenames and/or directory
424
    //                 names separated by spaces.
425
    //   $p_add_dir : A path to add before the real path of the archived file,
426
    //                in order to have it memorized in the archive.
427
    //   $p_remove_dir : A path to remove from the real path of the file to archive,
428
    //                   in order to have a shorter path memorized in the archive.
429
    //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
430
    //                   is removed first, before $p_add_dir is added.
431
    // Options :
432
    //   PCLZIP_OPT_ADD_PATH :
433
    //   PCLZIP_OPT_REMOVE_PATH :
434
    //   PCLZIP_OPT_REMOVE_ALL_PATH :
435
    //   PCLZIP_OPT_COMMENT :
436
    //   PCLZIP_OPT_ADD_COMMENT :
437
    //   PCLZIP_OPT_PREPEND_COMMENT :
438
    //   PCLZIP_CB_PRE_ADD :
439
    //   PCLZIP_CB_POST_ADD :
440
    // Return Values :
441
    //   0 on failure,
442
    //   The list of the added files, with a status of the add action.
443
    //   (see PclZip::listContent() for list entry format)
444
    // --------------------------------------------------------------------------------
445
    public function add($p_filelist)
446
    {
447
        $v_result = 1;
448
449
        // ----- Reset the error handler
450
        $this->privErrorReset();
451
452
        // ----- Set default values
453
        $v_options                            = array();
454
        $v_options[PCLZIP_OPT_NO_COMPRESSION] = false;
455
456
        // ----- Look for variable options arguments
457
        $v_size = func_num_args();
458
459
        // ----- Look for arguments
460
        if ($v_size > 1) {
461
            // ----- Get the arguments
462
            $v_arg_list = func_get_args();
463
464
            // ----- Remove form the options list the first argument
465
            array_shift($v_arg_list);
466
            $v_size--;
467
468
            // ----- Look for first arg
469
            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
470
471
                // ----- Parse the options
472
                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
473
                    PCLZIP_OPT_REMOVE_PATH => 'optional',
474
                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
475
                    PCLZIP_OPT_ADD_PATH => 'optional',
476
                    PCLZIP_CB_PRE_ADD => 'optional',
477
                    PCLZIP_CB_POST_ADD => 'optional',
478
                    PCLZIP_OPT_NO_COMPRESSION => 'optional',
479
                    PCLZIP_OPT_COMMENT => 'optional',
480
                    PCLZIP_OPT_ADD_COMMENT => 'optional',
481
                    PCLZIP_OPT_PREPEND_COMMENT => 'optional',
482
                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
483
                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
484
                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
485
                    //, PCLZIP_OPT_CRYPT => 'optional'
486
                ));
487
                if ($v_result != 1) {
488
                    return 0;
489
                }
490
491
            // ----- Look for 2 args
492
            // Here we need to support the first historic synopsis of the
493
            // method.
494
            } else {
495
496
                // ----- Get the first argument
497
                $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
0 ignored issues
show
Unused Code introduced by
The assignment to $v_add_path is dead and can be removed.
Loading history...
498
499
                // ----- Look for the optional second argument
500
                if ($v_size == 2) {
501
                    $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
502
                } elseif ($v_size > 2) {
503
                    // ----- Error log
504
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

504
                    PclZip::/** @scrutinizer ignore-call */ 
505
                            privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
Loading history...
505
506
                    // ----- Return
507
                    return 0;
508
                }
509
            }
510
        }
511
512
        // ----- Look for default option values
513
        $this->privOptionDefaultThreshold($v_options);
514
515
        // ----- Init
516
        $v_string_list    = array();
517
        $v_att_list       = array();
518
        $v_filedescr_list = array();
519
        $p_result_list    = array();
520
521
        // ----- Look if the $p_filelist is really an array
522
        if (is_array($p_filelist)) {
523
524
            // ----- Look if the first element is also an array
525
            //       This will mean that this is a file description entry
526
            if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
527
                $v_att_list = $p_filelist;
528
529
            // ----- The list is a list of string names
530
            } else {
531
                $v_string_list = $p_filelist;
532
            }
533
534
        // ----- Look if the $p_filelist is a string
535
        } elseif (is_string($p_filelist)) {
536
            // ----- Create a list from the string
537
            $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
538
539
        // ----- Invalid variable type for $p_filelist
540
        } else {
541
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '" . gettype($p_filelist) . "' for p_filelist");
542
543
            return 0;
544
        }
545
546
        // ----- Reformat the string list
547
        if (sizeof($v_string_list) != 0) {
548
            foreach ($v_string_list as $v_string) {
549
                $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
550
            }
551
        }
552
553
        // ----- For each file in the list check the attributes
554
        $v_supported_attributes = array(
555
            PCLZIP_ATT_FILE_NAME => 'mandatory',
556
            PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional',
557
            PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional',
558
            PCLZIP_ATT_FILE_MTIME => 'optional',
559
            PCLZIP_ATT_FILE_CONTENT => 'optional',
560
            PCLZIP_ATT_FILE_COMMENT => 'optional'
561
        );
562
        foreach ($v_att_list as $v_entry) {
563
            $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes);
564
            if ($v_result != 1) {
565
                return 0;
566
            }
567
        }
568
569
        // ----- Expand the filelist (expand directories)
570
        $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
571
        if ($v_result != 1) {
572
            return 0;
573
        }
574
575
        // ----- Call the create fct
576
        $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
577
        if ($v_result != 1) {
578
            return 0;
579
        }
580
581
        // ----- Return
582
        return $p_result_list;
583
    }
584
    // --------------------------------------------------------------------------------
585
586
    // --------------------------------------------------------------------------------
587
    // Function : listContent()
588
    // Description :
589
    //   This public method, gives the list of the files and directories, with their
590
    //   properties.
591
    //   The properties of each entries in the list are (used also in other functions) :
592
    //     filename : Name of the file. For a create or add action it is the filename
593
    //                given by the user. For an extract function it is the filename
594
    //                of the extracted file.
595
    //     stored_filename : Name of the file / directory stored in the archive.
596
    //     size : Size of the stored file.
597
    //     compressed_size : Size of the file's data compressed in the archive
598
    //                       (without the headers overhead)
599
    //     mtime : Last known modification date of the file (UNIX timestamp)
600
    //     comment : Comment associated with the file
601
    //     folder : true | false
602
    //     index : index of the file in the archive
603
    //     status : status of the action (depending of the action) :
604
    //              Values are :
605
    //                ok : OK !
606
    //                filtered : the file / dir is not extracted (filtered by user)
607
    //                already_a_directory : the file can not be extracted because a
608
    //                                      directory with the same name already exists
609
    //                write_protected : the file can not be extracted because a file
610
    //                                  with the same name already exists and is
611
    //                                  write protected
612
    //                newer_exist : the file was not extracted because a newer file exists
613
    //                path_creation_fail : the file is not extracted because the folder
614
    //                                     does not exist and can not be created
615
    //                write_error : the file was not extracted because there was a
616
    //                              error while writing the file
617
    //                read_error : the file was not extracted because there was a error
618
    //                             while reading the file
619
    //                invalid_header : the file was not extracted because of an archive
620
    //                                 format error (bad file header)
621
    //   Note that each time a method can continue operating when there
622
    //   is an action error on a file, the error is only logged in the file status.
623
    // Return Values :
624
    //   0 on an unrecoverable failure,
625
    //   The list of the files in the archive.
626
    // --------------------------------------------------------------------------------
627
    public function listContent()
628
    {
629
        $v_result = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
630
631
        // ----- Reset the error handler
632
        $this->privErrorReset();
633
634
        // ----- Check archive
635
        if (!$this->privCheckFormat()) {
636
            return (0);
637
        }
638
639
        // ----- Call the extracting fct
640
        $p_list = array();
641
        if (($v_result = $this->privList($p_list)) != 1) {
642
            unset($p_list);
643
644
            return (0);
645
        }
646
647
        // ----- Return
648
        return $p_list;
649
    }
650
    // --------------------------------------------------------------------------------
651
652
    // --------------------------------------------------------------------------------
653
    // Function :
654
    //   extract($p_path="./", $p_remove_path="")
655
    //   extract([$p_option, $p_option_value, ...])
656
    // Description :
657
    //   This method supports two synopsis. The first one is historical.
658
    //   This method extract all the files / directories from the archive to the
659
    //   folder indicated in $p_path.
660
    //   If you want to ignore the 'root' part of path of the memorized files
661
    //   you can indicate this in the optional $p_remove_path parameter.
662
    //   By default, if a newer file with the same name already exists, the
663
    //   file is not extracted.
664
    //
665
    //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
666
    //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
667
    //   at the end of the path value of PCLZIP_OPT_PATH.
668
    // Parameters :
669
    //   $p_path : Path where the files and directories are to be extracted
670
    //   $p_remove_path : First part ('root' part) of the memorized path
671
    //                    (if any similar) to remove while extracting.
672
    // Options :
673
    //   PCLZIP_OPT_PATH :
674
    //   PCLZIP_OPT_ADD_PATH :
675
    //   PCLZIP_OPT_REMOVE_PATH :
676
    //   PCLZIP_OPT_REMOVE_ALL_PATH :
677
    //   PCLZIP_CB_PRE_EXTRACT :
678
    //   PCLZIP_CB_POST_EXTRACT :
679
    // Return Values :
680
    //   0 or a negative value on failure,
681
    //   The list of the extracted files, with a status of the action.
682
    //   (see PclZip::listContent() for list entry format)
683
    // --------------------------------------------------------------------------------
684
    public function extract()
685
    {
686
        $v_result = 1;
687
688
        // ----- Reset the error handler
689
        $this->privErrorReset();
690
691
        // ----- Check archive
692
        if (!$this->privCheckFormat()) {
693
            return (0);
694
        }
695
696
        // ----- Set default values
697
        $v_options         = array();
698
        //    $v_path = "./";
699
        $v_path            = '';
700
        $v_remove_path     = "";
701
        $v_remove_all_path = false;
702
703
        // ----- Look for variable options arguments
704
        $v_size = func_num_args();
705
706
        // ----- Default values for option
707
        $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
708
709
        // ----- Look for arguments
710
        if ($v_size > 0) {
711
            // ----- Get the arguments
712
            $v_arg_list = func_get_args();
713
714
            // ----- Look for first arg
715
            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
716
717
                // ----- Parse the options
718
                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
719
                    PCLZIP_OPT_PATH => 'optional',
720
                    PCLZIP_OPT_REMOVE_PATH => 'optional',
721
                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
722
                    PCLZIP_OPT_ADD_PATH => 'optional',
723
                    PCLZIP_CB_PRE_EXTRACT => 'optional',
724
                    PCLZIP_CB_POST_EXTRACT => 'optional',
725
                    PCLZIP_OPT_SET_CHMOD => 'optional',
726
                    PCLZIP_OPT_BY_NAME => 'optional',
727
                    PCLZIP_OPT_BY_EREG => 'optional',
728
                    PCLZIP_OPT_BY_PREG => 'optional',
729
                    PCLZIP_OPT_BY_INDEX => 'optional',
730
                    PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
731
                    PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
732
                    PCLZIP_OPT_REPLACE_NEWER => 'optional',
733
                    PCLZIP_OPT_STOP_ON_ERROR => 'optional',
734
                    PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
735
                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
736
                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
737
                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
738
                ));
739
                if ($v_result != 1) {
740
                    return 0;
741
                }
742
743
                // ----- Set the arguments
744
                if (isset($v_options[PCLZIP_OPT_PATH])) {
745
                    $v_path = $v_options[PCLZIP_OPT_PATH];
746
                }
747
                if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
748
                    $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
749
                }
750
                if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
751
                    $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
752
                }
753
                if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
754
                    // ----- Check for '/' in last path char
755
                    if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
756
                        $v_path .= '/';
757
                    }
758
                    $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
759
                }
760
761
            // ----- Look for 2 args
762
            // Here we need to support the first historic synopsis of the
763
            // method.
764
            } else {
765
766
                // ----- Get the first argument
767
                $v_path = $v_arg_list[0];
768
769
                // ----- Look for the optional second argument
770
                if ($v_size == 2) {
771
                    $v_remove_path = $v_arg_list[1];
772
                } elseif ($v_size > 2) {
773
                    // ----- Error log
774
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

774
                    PclZip::/** @scrutinizer ignore-call */ 
775
                            privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
Loading history...
775
776
                    // ----- Return
777
                    return 0;
778
                }
779
            }
780
        }
781
782
        // ----- Look for default option values
783
        $this->privOptionDefaultThreshold($v_options);
784
785
        // ----- Trace
786
787
        // ----- Call the extracting fct
788
        $p_list   = array();
789
        $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options);
790
        if ($v_result < 1) {
791
            unset($p_list);
792
793
            return (0);
794
        }
795
796
        // ----- Return
797
        return $p_list;
798
    }
799
    // --------------------------------------------------------------------------------
800
801
802
    // --------------------------------------------------------------------------------
803
    // Function :
804
    //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
805
    //   extractByIndex($p_index, [$p_option, $p_option_value, ...])
806
    // Description :
807
    //   This method supports two synopsis. The first one is historical.
808
    //   This method is doing a partial extract of the archive.
809
    //   The extracted files or folders are identified by their index in the
810
    //   archive (from 0 to n).
811
    //   Note that if the index identify a folder, only the folder entry is
812
    //   extracted, not all the files included in the archive.
813
    // Parameters :
814
    //   $p_index : A single index (integer) or a string of indexes of files to
815
    //              extract. The form of the string is "0,4-6,8-12" with only numbers
816
    //              and '-' for range or ',' to separate ranges. No spaces or ';'
817
    //              are allowed.
818
    //   $p_path : Path where the files and directories are to be extracted
819
    //   $p_remove_path : First part ('root' part) of the memorized path
820
    //                    (if any similar) to remove while extracting.
821
    // Options :
822
    //   PCLZIP_OPT_PATH :
823
    //   PCLZIP_OPT_ADD_PATH :
824
    //   PCLZIP_OPT_REMOVE_PATH :
825
    //   PCLZIP_OPT_REMOVE_ALL_PATH :
826
    //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
827
    //     not as files.
828
    //     The resulting content is in a new field 'content' in the file
829
    //     structure.
830
    //     This option must be used alone (any other options are ignored).
831
    //   PCLZIP_CB_PRE_EXTRACT :
832
    //   PCLZIP_CB_POST_EXTRACT :
833
    // Return Values :
834
    //   0 on failure,
835
    //   The list of the extracted files, with a status of the action.
836
    //   (see PclZip::listContent() for list entry format)
837
    // --------------------------------------------------------------------------------
838
    //function extractByIndex($p_index, options...)
839
    public function extractByIndex($p_index)
840
    {
841
        $v_result = 1;
842
843
        // ----- Reset the error handler
844
        $this->privErrorReset();
845
846
        // ----- Check archive
847
        if (!$this->privCheckFormat()) {
848
            return (0);
849
        }
850
851
        // ----- Set default values
852
        $v_options         = array();
853
        //    $v_path = "./";
854
        $v_path            = '';
855
        $v_remove_path     = "";
856
        $v_remove_all_path = false;
857
858
        // ----- Look for variable options arguments
859
        $v_size = func_num_args();
860
861
        // ----- Default values for option
862
        $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
863
864
        // ----- Look for arguments
865
        if ($v_size > 1) {
866
            // ----- Get the arguments
867
            $v_arg_list = func_get_args();
868
869
            // ----- Remove form the options list the first argument
870
            array_shift($v_arg_list);
871
            $v_size--;
872
873
            // ----- Look for first arg
874
            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
875
876
                // ----- Parse the options
877
                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
878
                    PCLZIP_OPT_PATH => 'optional',
879
                    PCLZIP_OPT_REMOVE_PATH => 'optional',
880
                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
881
                    PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
882
                    PCLZIP_OPT_ADD_PATH => 'optional',
883
                    PCLZIP_CB_PRE_EXTRACT => 'optional',
884
                    PCLZIP_CB_POST_EXTRACT => 'optional',
885
                    PCLZIP_OPT_SET_CHMOD => 'optional',
886
                    PCLZIP_OPT_REPLACE_NEWER => 'optional',
887
                    PCLZIP_OPT_STOP_ON_ERROR => 'optional',
888
                    PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
889
                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
890
                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
891
                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
892
                ));
893
                if ($v_result != 1) {
894
                    return 0;
895
                }
896
897
                // ----- Set the arguments
898
                if (isset($v_options[PCLZIP_OPT_PATH])) {
899
                    $v_path = $v_options[PCLZIP_OPT_PATH];
900
                }
901
                if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
902
                    $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
903
                }
904
                if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
905
                    $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
906
                }
907
                if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
908
                    // ----- Check for '/' in last path char
909
                    if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
910
                        $v_path .= '/';
911
                    }
912
                    $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
913
                }
914
                if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
915
                    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
916
                } else {
917
                }
918
919
            // ----- Look for 2 args
920
            // Here we need to support the first historic synopsis of the
921
            // method.
922
            } else {
923
924
                // ----- Get the first argument
925
                $v_path = $v_arg_list[0];
926
927
                // ----- Look for the optional second argument
928
                if ($v_size == 2) {
929
                    $v_remove_path = $v_arg_list[1];
930
                } elseif ($v_size > 2) {
931
                    // ----- Error log
932
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

932
                    PclZip::/** @scrutinizer ignore-call */ 
933
                            privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
Loading history...
933
934
                    // ----- Return
935
                    return 0;
936
                }
937
            }
938
        }
939
940
        // ----- Trace
941
942
        // ----- Trick
943
        // Here I want to reuse extractByRule(), so I need to parse the $p_index
944
        // with privParseOptions()
945
        $v_arg_trick     = array(
946
            PCLZIP_OPT_BY_INDEX,
947
            $p_index
948
        );
949
        $v_options_trick = array();
950
        $v_result        = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, array(
951
            PCLZIP_OPT_BY_INDEX => 'optional'
952
        ));
953
        if ($v_result != 1) {
954
            return 0;
955
        }
956
        $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
957
958
        // ----- Look for default option values
959
        $this->privOptionDefaultThreshold($v_options);
960
961
        // ----- Call the extracting fct
962
        if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
963
            return (0);
964
        }
965
966
        // ----- Return
967
        return $p_list;
968
    }
969
    // --------------------------------------------------------------------------------
970
971
    // --------------------------------------------------------------------------------
972
    // Function :
973
    //   delete([$p_option, $p_option_value, ...])
974
    // Description :
975
    //   This method removes files from the archive.
976
    //   If no parameters are given, then all the archive is emptied.
977
    // Parameters :
978
    //   None or optional arguments.
979
    // Options :
980
    //   PCLZIP_OPT_BY_INDEX :
981
    //   PCLZIP_OPT_BY_NAME :
982
    //   PCLZIP_OPT_BY_EREG :
983
    //   PCLZIP_OPT_BY_PREG :
984
    // Return Values :
985
    //   0 on failure,
986
    //   The list of the files which are still present in the archive.
987
    //   (see PclZip::listContent() for list entry format)
988
    // --------------------------------------------------------------------------------
989
    public function delete()
990
    {
991
        $v_result = 1;
992
993
        // ----- Reset the error handler
994
        $this->privErrorReset();
995
996
        // ----- Check archive
997
        if (!$this->privCheckFormat()) {
998
            return (0);
999
        }
1000
1001
        // ----- Set default values
1002
        $v_options = array();
1003
1004
        // ----- Look for variable options arguments
1005
        $v_size = func_num_args();
1006
1007
        // ----- Look for arguments
1008
        if ($v_size > 0) {
1009
            // ----- Get the arguments
1010
            $v_arg_list = func_get_args();
1011
1012
            // ----- Parse the options
1013
            $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
1014
                PCLZIP_OPT_BY_NAME => 'optional',
1015
                PCLZIP_OPT_BY_EREG => 'optional',
1016
                PCLZIP_OPT_BY_PREG => 'optional',
1017
                PCLZIP_OPT_BY_INDEX => 'optional'
1018
            ));
1019
            if ($v_result != 1) {
1020
                return 0;
1021
            }
1022
        }
1023
1024
        // ----- Magic quotes trick
1025
        $this->privDisableMagicQuotes();
1026
1027
        // ----- Call the delete fct
1028
        $v_list = array();
1029
        if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
1030
            $this->privSwapBackMagicQuotes();
1031
            unset($v_list);
1032
1033
            return (0);
1034
        }
1035
1036
        // ----- Magic quotes trick
1037
        $this->privSwapBackMagicQuotes();
1038
1039
        // ----- Return
1040
        return $v_list;
1041
    }
1042
    // --------------------------------------------------------------------------------
1043
1044
    // --------------------------------------------------------------------------------
1045
    // Function : deleteByIndex()
1046
    // Description :
1047
    //   ***** Deprecated *****
1048
    //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1049
    // --------------------------------------------------------------------------------
1050
    public function deleteByIndex($p_index)
1051
    {
1052
1053
        $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1054
1055
        // ----- Return
1056
        return $p_list;
1057
    }
1058
    // --------------------------------------------------------------------------------
1059
1060
    // --------------------------------------------------------------------------------
1061
    // Function : properties()
1062
    // Description :
1063
    //   This method gives the properties of the archive.
1064
    //   The properties are :
1065
    //     nb : Number of files in the archive
1066
    //     comment : Comment associated with the archive file
1067
    //     status : not_exist, ok
1068
    // Parameters :
1069
    //   None
1070
    // Return Values :
1071
    //   0 on failure,
1072
    //   An array with the archive properties.
1073
    // --------------------------------------------------------------------------------
1074
    public function properties()
1075
    {
1076
1077
        // ----- Reset the error handler
1078
        $this->privErrorReset();
1079
1080
        // ----- Magic quotes trick
1081
        $this->privDisableMagicQuotes();
1082
1083
        // ----- Check archive
1084
        if (!$this->privCheckFormat()) {
1085
            $this->privSwapBackMagicQuotes();
1086
1087
            return (0);
1088
        }
1089
1090
        // ----- Default properties
1091
        $v_prop            = array();
1092
        $v_prop['comment'] = '';
1093
        $v_prop['nb']      = 0;
1094
        $v_prop['status']  = 'not_exist';
1095
1096
        // ----- Look if file exists
1097
        if (@is_file($this->zipname)) {
1098
            // ----- Open the zip file
1099
            if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) {
1100
                $this->privSwapBackMagicQuotes();
1101
1102
                // ----- Error log
1103
                PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1103
                PclZip::/** @scrutinizer ignore-call */ 
1104
                        privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode');
Loading history...
1104
1105
                // ----- Return
1106
                return 0;
1107
            }
1108
1109
            // ----- Read the central directory informations
1110
            $v_central_dir = array();
1111
            if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
1112
                $this->privSwapBackMagicQuotes();
1113
1114
                return 0;
1115
            }
1116
1117
            // ----- Close the zip file
1118
            $this->privCloseFd();
1119
1120
            // ----- Set the user attributes
1121
            $v_prop['comment'] = $v_central_dir['comment'];
1122
            $v_prop['nb']      = $v_central_dir['entries'];
1123
            $v_prop['status']  = 'ok';
1124
        }
1125
1126
        // ----- Magic quotes trick
1127
        $this->privSwapBackMagicQuotes();
1128
1129
        // ----- Return
1130
        return $v_prop;
1131
    }
1132
    // --------------------------------------------------------------------------------
1133
1134
    // --------------------------------------------------------------------------------
1135
    // Function : duplicate()
1136
    // Description :
1137
    //   This method creates an archive by copying the content of an other one. If
1138
    //   the archive already exist, it is replaced by the new one without any warning.
1139
    // Parameters :
1140
    //   $p_archive : The filename of a valid archive, or
1141
    //                a valid PclZip object.
1142
    // Return Values :
1143
    //   1 on success.
1144
    //   0 or a negative value on error (error code).
1145
    // --------------------------------------------------------------------------------
1146
    public function duplicate($p_archive)
1147
    {
1148
        $v_result = 1;
1149
1150
        // ----- Reset the error handler
1151
        $this->privErrorReset();
1152
1153
        // ----- Look if the $p_archive is a PclZip object
1154
        if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) {
1155
1156
            // ----- Duplicate the archive
1157
            $v_result = $this->privDuplicate($p_archive->zipname);
1158
1159
        // ----- Look if the $p_archive is a string (so a filename)
1160
        } elseif (is_string($p_archive)) {
1161
1162
            // ----- Check that $p_archive is a valid zip file
1163
            // TBC : Should also check the archive format
1164
            if (!is_file($p_archive)) {
1165
                // ----- Error log
1166
                PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '" . $p_archive . "'");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1166
                PclZip::/** @scrutinizer ignore-call */ 
1167
                        privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '" . $p_archive . "'");
Loading history...
1167
                $v_result = PCLZIP_ERR_MISSING_FILE;
1168
            } else {
1169
                // ----- Duplicate the archive
1170
                $v_result = $this->privDuplicate($p_archive);
1171
            }
1172
1173
        // ----- Invalid variable
1174
        } else {
1175
            // ----- Error log
1176
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1177
            $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1178
        }
1179
1180
        // ----- Return
1181
        return $v_result;
1182
    }
1183
    // --------------------------------------------------------------------------------
1184
1185
    // --------------------------------------------------------------------------------
1186
    // Function : merge()
1187
    // Description :
1188
    //   This method merge the $p_archive_to_add archive at the end of the current
1189
    //   one ($this).
1190
    //   If the archive ($this) does not exist, the merge becomes a duplicate.
1191
    //   If the $p_archive_to_add archive does not exist, the merge is a success.
1192
    // Parameters :
1193
    //   $p_archive_to_add : It can be directly the filename of a valid zip archive,
1194
    //                       or a PclZip object archive.
1195
    // Return Values :
1196
    //   1 on success,
1197
    //   0 or negative values on error (see below).
1198
    // --------------------------------------------------------------------------------
1199
    public function merge($p_archive_to_add)
1200
    {
1201
        $v_result = 1;
1202
1203
        // ----- Reset the error handler
1204
        $this->privErrorReset();
1205
1206
        // ----- Check archive
1207
        if (!$this->privCheckFormat()) {
1208
            return (0);
1209
        }
1210
1211
        // ----- Look if the $p_archive_to_add is a PclZip object
1212
        if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) {
1213
1214
            // ----- Merge the archive
1215
            $v_result = $this->privMerge($p_archive_to_add);
1216
1217
        // ----- Look if the $p_archive_to_add is a string (so a filename)
1218
        } elseif (is_string($p_archive_to_add)) {
1219
1220
            // ----- Create a temporary archive
1221
            $v_object_archive = new PclZip($p_archive_to_add);
1222
1223
            // ----- Merge the archive
1224
            $v_result = $this->privMerge($v_object_archive);
1225
1226
        // ----- Invalid variable
1227
        } else {
1228
            // ----- Error log
1229
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1229
            PclZip::/** @scrutinizer ignore-call */ 
1230
                    privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
Loading history...
1230
            $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1231
        }
1232
1233
        // ----- Return
1234
        return $v_result;
1235
    }
1236
    // --------------------------------------------------------------------------------
1237
1238
    // --------------------------------------------------------------------------------
1239
    // Function : errorCode()
1240
    // Description :
1241
    // Parameters :
1242
    // --------------------------------------------------------------------------------
1243
    public function errorCode()
1244
    {
1245
        if (PCLZIP_ERROR_EXTERNAL == 1) {
0 ignored issues
show
introduced by
The condition PCLZIP_ERROR_EXTERNAL == 1 is always false.
Loading history...
1246
            return (PclErrorCode());
0 ignored issues
show
Bug introduced by
The function PclErrorCode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1246
            return (/** @scrutinizer ignore-call */ PclErrorCode());
Loading history...
1247
        }
1248
1249
        return ($this->error_code);
1250
    }
1251
    // --------------------------------------------------------------------------------
1252
1253
    // --------------------------------------------------------------------------------
1254
    // Function : errorName()
1255
    // Description :
1256
    // Parameters :
1257
    // --------------------------------------------------------------------------------
1258
    public function errorName($p_with_code = false)
1259
    {
1260
        $v_name = array(
1261
            PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1262
            PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1263
            PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1264
            PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1265
            PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1266
            PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1267
            PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1268
            PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1269
            PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1270
            PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1271
            PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1272
            PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1273
            PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1274
            PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1275
            PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1276
            PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1277
            PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1278
            PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1279
            PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION',
1280
            PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE',
1281
            PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1282
        );
1283
1284
        if (isset($v_name[$this->error_code])) {
1285
            $v_value = $v_name[$this->error_code];
1286
        } else {
1287
            $v_value = 'NoName';
1288
        }
1289
1290
        if ($p_with_code) {
1291
            return ($v_value . ' (' . $this->error_code . ')');
1292
        }
1293
1294
        return ($v_value);
1295
    }
1296
    // --------------------------------------------------------------------------------
1297
1298
    // --------------------------------------------------------------------------------
1299
    // Function : errorInfo()
1300
    // Description :
1301
    // Parameters :
1302
    // --------------------------------------------------------------------------------
1303
    public function errorInfo($p_full = false)
1304
    {
1305
        if (PCLZIP_ERROR_EXTERNAL == 1) {
0 ignored issues
show
introduced by
The condition PCLZIP_ERROR_EXTERNAL == 1 is always false.
Loading history...
1306
            return (PclErrorString());
0 ignored issues
show
Bug introduced by
The function PclErrorString was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1306
            return (/** @scrutinizer ignore-call */ PclErrorString());
Loading history...
1307
        }
1308
1309
        if ($p_full) {
1310
            return ($this->errorName(true) . " : " . $this->error_string);
1311
        }
1312
1313
        return ($this->error_string . " [code " . $this->error_code . "]");
1314
    }
1315
    // --------------------------------------------------------------------------------
1316
1317
    // --------------------------------------------------------------------------------
1318
    // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1319
    // *****                                                        *****
1320
    // *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
1321
    // --------------------------------------------------------------------------------
1322
1323
    // --------------------------------------------------------------------------------
1324
    // Function : privCheckFormat()
1325
    // Description :
1326
    //   This method check that the archive exists and is a valid zip archive.
1327
    //   Several level of check exists. (futur)
1328
    // Parameters :
1329
    //   $p_level : Level of check. Default 0.
1330
    //              0 : Check the first bytes (magic codes) (default value))
1331
    //              1 : 0 + Check the central directory (futur)
1332
    //              2 : 1 + Check each file header (futur)
1333
    // Return Values :
1334
    //   true on success,
1335
    //   false on error, the error code is set.
1336
    // --------------------------------------------------------------------------------
1337
    public function privCheckFormat($p_level = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $p_level is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1337
    public function privCheckFormat(/** @scrutinizer ignore-unused */ $p_level = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1338
    {
1339
        $v_result = true;
1340
1341
        // ----- Reset the file system cache
1342
        clearstatcache();
1343
1344
        // ----- Reset the error handler
1345
        $this->privErrorReset();
1346
1347
        // ----- Look if the file exits
1348
        if (!is_file($this->zipname)) {
1349
            // ----- Error log
1350
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '" . $this->zipname . "'");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1350
            PclZip::/** @scrutinizer ignore-call */ 
1351
                    privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '" . $this->zipname . "'");
Loading history...
1351
1352
            return (false);
1353
        }
1354
1355
        // ----- Check that the file is readeable
1356
        if (!is_readable($this->zipname)) {
1357
            // ----- Error log
1358
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '" . $this->zipname . "'");
1359
1360
            return (false);
1361
        }
1362
1363
        // ----- Check the magic code
1364
        // TBC
1365
1366
        // ----- Check the central header
1367
        // TBC
1368
1369
        // ----- Check each file header
1370
        // TBC
1371
1372
        // ----- Return
1373
        return $v_result;
1374
    }
1375
    // --------------------------------------------------------------------------------
1376
1377
    // --------------------------------------------------------------------------------
1378
    // Function : privParseOptions()
1379
    // Description :
1380
    //   This internal methods reads the variable list of arguments ($p_options_list,
1381
    //   $p_size) and generate an array with the options and values ($v_result_list).
1382
    //   $v_requested_options contains the options that can be present and those that
1383
    //   must be present.
1384
    //   $v_requested_options is an array, with the option value as key, and 'optional',
1385
    //   or 'mandatory' as value.
1386
    // Parameters :
1387
    //   See above.
1388
    // Return Values :
1389
    //   1 on success.
1390
    //   0 on failure.
1391
    // --------------------------------------------------------------------------------
1392
    public function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options = false)
1393
    {
1394
        $v_result = 1;
1395
1396
        // ----- Read the options
1397
        $i = 0;
1398
        while ($i < $p_size) {
1399
1400
            // ----- Check if the option is supported
1401
            if (!isset($v_requested_options[$p_options_list[$i]])) {
1402
                // ----- Error log
1403
                PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '" . $p_options_list[$i] . "' for this method");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1403
                PclZip::/** @scrutinizer ignore-call */ 
1404
                        privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '" . $p_options_list[$i] . "' for this method");
Loading history...
1404
1405
                // ----- Return
1406
                return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1406
                return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
1407
            }
1408
1409
            // ----- Look for next option
1410
            switch ($p_options_list[$i]) {
1411
                // ----- Look for options that request a path value
1412
                case PCLZIP_OPT_PATH:
1413
                case PCLZIP_OPT_REMOVE_PATH:
1414
                case PCLZIP_OPT_ADD_PATH:
1415
                    // ----- Check the number of parameters
1416
                    if (($i + 1) >= $p_size) {
1417
                        // ----- Error log
1418
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1419
1420
                        // ----- Return
1421
                        return PclZip::errorCode();
1422
                    }
1423
1424
                    // ----- Get the value
1425
                    $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i + 1], false);
1426
                    $i++;
1427
                    break;
1428
1429
                case PCLZIP_OPT_TEMP_FILE_THRESHOLD:
1430
                    // ----- Check the number of parameters
1431
                    if (($i + 1) >= $p_size) {
1432
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1433
1434
                        return PclZip::errorCode();
1435
                    }
1436
1437
                    // ----- Check for incompatible options
1438
                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1439
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1440
1441
                        return PclZip::errorCode();
1442
                    }
1443
1444
                    // ----- Check the value
1445
                    $v_value = $p_options_list[$i + 1];
1446
                    if ((!is_integer($v_value)) || ($v_value < 0)) {
1447
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1448
1449
                        return PclZip::errorCode();
1450
                    }
1451
1452
                    // ----- Get the value (and convert it in bytes)
1453
                    $v_result_list[$p_options_list[$i]] = $v_value * 1048576;
1454
                    $i++;
1455
                    break;
1456
1457
                case PCLZIP_OPT_TEMP_FILE_ON:
1458
                    // ----- Check for incompatible options
1459
                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1460
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1461
1462
                        return PclZip::errorCode();
1463
                    }
1464
1465
                    $v_result_list[$p_options_list[$i]] = true;
1466
                    break;
1467
1468
                case PCLZIP_OPT_TEMP_FILE_OFF:
1469
                    // ----- Check for incompatible options
1470
                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1471
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1472
1473
                        return PclZip::errorCode();
1474
                    }
1475
                    // ----- Check for incompatible options
1476
                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1477
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1478
1479
                        return PclZip::errorCode();
1480
                    }
1481
1482
                    $v_result_list[$p_options_list[$i]] = true;
1483
                    break;
1484
1485
                case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION:
1486
                    // ----- Check the number of parameters
1487
                    if (($i + 1) >= $p_size) {
1488
                        // ----- Error log
1489
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1490
1491
                        // ----- Return
1492
                        return PclZip::errorCode();
1493
                    }
1494
1495
                    // ----- Get the value
1496
                    if (is_string($p_options_list[$i + 1]) && ($p_options_list[$i + 1] != '')) {
1497
                        $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i + 1], false);
1498
                        $i++;
1499
                    } else {
1500
                    }
1501
                    break;
1502
1503
                // ----- Look for options that request an array of string for value
1504
                case PCLZIP_OPT_BY_NAME:
1505
                    // ----- Check the number of parameters
1506
                    if (($i + 1) >= $p_size) {
1507
                        // ----- Error log
1508
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1509
1510
                        // ----- Return
1511
                        return PclZip::errorCode();
1512
                    }
1513
1514
                    // ----- Get the value
1515
                    if (is_string($p_options_list[$i + 1])) {
1516
                        $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i + 1];
1517
                    } elseif (is_array($p_options_list[$i + 1])) {
1518
                        $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
1519
                    } else {
1520
                        // ----- Error log
1521
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1522
1523
                        // ----- Return
1524
                        return PclZip::errorCode();
1525
                    }
1526
                    $i++;
1527
                    break;
1528
1529
                // ----- Look for options that request an EREG or PREG expression
1530
                case PCLZIP_OPT_BY_EREG:
1531
                    $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1532
                    // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
1533
                    // to PCLZIP_OPT_BY_PREG
1534
                case PCLZIP_OPT_BY_PREG:
1535
                    //case PCLZIP_OPT_CRYPT :
1536
                    // ----- Check the number of parameters
1537
                    if (($i + 1) >= $p_size) {
1538
                        // ----- Error log
1539
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1540
1541
                        // ----- Return
1542
                        return PclZip::errorCode();
1543
                    }
1544
1545
                    // ----- Get the value
1546
                    if (is_string($p_options_list[$i + 1])) {
1547
                        $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
1548
                    } else {
1549
                        // ----- Error log
1550
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1551
1552
                        // ----- Return
1553
                        return PclZip::errorCode();
1554
                    }
1555
                    $i++;
1556
                    break;
1557
1558
                // ----- Look for options that takes a string
1559
                case PCLZIP_OPT_COMMENT:
1560
                case PCLZIP_OPT_ADD_COMMENT:
1561
                case PCLZIP_OPT_PREPEND_COMMENT:
1562
                    // ----- Check the number of parameters
1563
                    if (($i + 1) >= $p_size) {
1564
                        // ----- Error log
1565
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1566
1567
                        // ----- Return
1568
                        return PclZip::errorCode();
1569
                    }
1570
1571
                    // ----- Get the value
1572
                    if (is_string($p_options_list[$i + 1])) {
1573
                        $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
1574
                    } else {
1575
                        // ----- Error log
1576
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1577
1578
                        // ----- Return
1579
                        return PclZip::errorCode();
1580
                    }
1581
                    $i++;
1582
                    break;
1583
1584
                // ----- Look for options that request an array of index
1585
                case PCLZIP_OPT_BY_INDEX:
1586
                    // ----- Check the number of parameters
1587
                    if (($i + 1) >= $p_size) {
1588
                        // ----- Error log
1589
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1590
1591
                        // ----- Return
1592
                        return PclZip::errorCode();
1593
                    }
1594
1595
                    // ----- Get the value
1596
                    $v_work_list = array();
1597
                    if (is_string($p_options_list[$i + 1])) {
1598
1599
                        // ----- Remove spaces
1600
                        $p_options_list[$i + 1] = strtr($p_options_list[$i + 1], ' ', '');
1601
1602
                        // ----- Parse items
1603
                        $v_work_list = explode(",", $p_options_list[$i + 1]);
1604
                    } elseif (is_integer($p_options_list[$i + 1])) {
1605
                        $v_work_list[0] = $p_options_list[$i + 1] . '-' . $p_options_list[$i + 1];
1606
                    } elseif (is_array($p_options_list[$i + 1])) {
1607
                        $v_work_list = $p_options_list[$i + 1];
1608
                    } else {
1609
                        // ----- Error log
1610
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1611
1612
                        // ----- Return
1613
                        return PclZip::errorCode();
1614
                    }
1615
1616
                    // ----- Reduce the index list
1617
                    // each index item in the list must be a couple with a start and
1618
                    // an end value : [0,3], [5-5], [8-10], ...
1619
                    // ----- Check the format of each item
1620
                    $v_sort_flag  = false;
1621
                    $v_sort_value = 0;
1622
                    for ($j = 0; $j < sizeof($v_work_list); $j++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1623
                        // ----- Explode the item
1624
                        $v_item_list      = explode("-", $v_work_list[$j]);
1625
                        $v_size_item_list = sizeof($v_item_list);
1626
1627
                        // ----- TBC : Here we might check that each item is a
1628
                        // real integer ...
1629
1630
                        // ----- Look for single value
1631
                        if ($v_size_item_list == 1) {
1632
                            // ----- Set the option value
1633
                            $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1634
                            $v_result_list[$p_options_list[$i]][$j]['end']   = $v_item_list[0];
1635
                        } elseif ($v_size_item_list == 2) {
1636
                            // ----- Set the option value
1637
                            $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1638
                            $v_result_list[$p_options_list[$i]][$j]['end']   = $v_item_list[1];
1639
                        } else {
1640
                            // ----- Error log
1641
                            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1642
1643
                            // ----- Return
1644
                            return PclZip::errorCode();
1645
                        }
1646
1647
                        // ----- Look for list sort
1648
                        if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1649
                            $v_sort_flag = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_sort_flag is dead and can be removed.
Loading history...
1650
1651
                            // ----- TBC : An automatic sort should be writen ...
1652
                            // ----- Error log
1653
                            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1654
1655
                            // ----- Return
1656
                            return PclZip::errorCode();
1657
                        }
1658
                        $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1659
                    }
1660
1661
                    // ----- Sort the items
1662
                    if ($v_sort_flag) {
1663
                        // TBC : To Be Completed
1664
                    }
1665
1666
                    // ----- Next option
1667
                    $i++;
1668
                    break;
1669
1670
                // ----- Look for options that request no value
1671
                case PCLZIP_OPT_REMOVE_ALL_PATH:
1672
                case PCLZIP_OPT_EXTRACT_AS_STRING:
1673
                case PCLZIP_OPT_NO_COMPRESSION:
1674
                case PCLZIP_OPT_EXTRACT_IN_OUTPUT:
1675
                case PCLZIP_OPT_REPLACE_NEWER:
1676
                case PCLZIP_OPT_STOP_ON_ERROR:
1677
                    $v_result_list[$p_options_list[$i]] = true;
1678
                    break;
1679
1680
                // ----- Look for options that request an octal value
1681
                case PCLZIP_OPT_SET_CHMOD:
1682
                    // ----- Check the number of parameters
1683
                    if (($i + 1) >= $p_size) {
1684
                        // ----- Error log
1685
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1686
1687
                        // ----- Return
1688
                        return PclZip::errorCode();
1689
                    }
1690
1691
                    // ----- Get the value
1692
                    $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
1693
                    $i++;
1694
                    break;
1695
1696
                // ----- Look for options that request a call-back
1697
                case PCLZIP_CB_PRE_EXTRACT:
1698
                case PCLZIP_CB_POST_EXTRACT:
1699
                case PCLZIP_CB_PRE_ADD:
1700
                case PCLZIP_CB_POST_ADD:
1701
                    /* for futur use
1702
                    case PCLZIP_CB_PRE_DELETE :
1703
                    case PCLZIP_CB_POST_DELETE :
1704
                    case PCLZIP_CB_PRE_LIST :
1705
                    case PCLZIP_CB_POST_LIST :
1706
                    */
1707
                    // ----- Check the number of parameters
1708
                    if (($i + 1) >= $p_size) {
1709
                        // ----- Error log
1710
                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1711
1712
                        // ----- Return
1713
                        return PclZip::errorCode();
1714
                    }
1715
1716
                    // ----- Get the value
1717
                    $v_function_name = $p_options_list[$i + 1];
1718
1719
                    // ----- Check that the value is a valid existing function
1720
                    if (!function_exists($v_function_name)) {
1721
                        // ----- Error log
1722
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '" . $v_function_name . "()' is not an existing function for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
1723
1724
                        // ----- Return
1725
                        return PclZip::errorCode();
1726
                    }
1727
1728
                    // ----- Set the attribute
1729
                    $v_result_list[$p_options_list[$i]] = $v_function_name;
1730
                    $i++;
1731
                    break;
1732
1733
                default:
1734
                    // ----- Error log
1735
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" . $p_options_list[$i] . "'");
1736
1737
                    // ----- Return
1738
                    return PclZip::errorCode();
1739
            }
1740
1741
            // ----- Next options
1742
            $i++;
1743
        }
1744
1745
        // ----- Look for mandatory options
1746
        if ($v_requested_options !== false) {
1747
            for ($key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $key is dead and can be removed.
Loading history...
1748
                // ----- Look for mandatory option
1749
                if ($v_requested_options[$key] == 'mandatory') {
1750
                    // ----- Look if present
1751
                    if (!isset($v_result_list[$key])) {
1752
                        // ----- Error log
1753
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")");
1754
1755
                        // ----- Return
1756
                        return PclZip::errorCode();
1757
                    }
1758
                }
1759
            }
1760
        }
1761
1762
        // ----- Look for default values
1763
        if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1764
1765
        }
1766
1767
        // ----- Return
1768
        return $v_result;
1769
    }
1770
    // --------------------------------------------------------------------------------
1771
1772
    // --------------------------------------------------------------------------------
1773
    // Function : privOptionDefaultThreshold()
1774
    // Description :
1775
    // Parameters :
1776
    // Return Values :
1777
    // --------------------------------------------------------------------------------
1778
    public function privOptionDefaultThreshold(&$p_options)
1779
    {
1780
        $v_result = 1;
1781
1782
        if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1783
            return $v_result;
1784
        }
1785
1786
        // ----- Get 'memory_limit' configuration value
1787
        $v_memory_limit = ini_get('memory_limit');
1788
        $v_memory_limit = trim($v_memory_limit);
1789
        $last           = strtolower(substr($v_memory_limit, -1));
1790
        $v_memory_limit = preg_replace('/[^0-9,.]/', '', $v_memory_limit);
1791
1792
        if ($last == 'g') {
1793
            //$v_memory_limit = $v_memory_limit*1024*1024*1024;
1794
            $v_memory_limit = $v_memory_limit * 1073741824;
1795
        }
1796
        if ($last == 'm') {
1797
            //$v_memory_limit = $v_memory_limit*1024*1024;
1798
            $v_memory_limit = $v_memory_limit * 1048576;
1799
        }
1800
        if ($last == 'k') {
1801
            $v_memory_limit = $v_memory_limit * 1024;
1802
        }
1803
1804
        $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit * PCLZIP_TEMPORARY_FILE_RATIO);
1805
1806
        // ----- Sanity check : No threshold if value lower than 1M
1807
        if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1808
            unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1809
        }
1810
1811
        // ----- Return
1812
        return $v_result;
1813
    }
1814
    // --------------------------------------------------------------------------------
1815
1816
    // --------------------------------------------------------------------------------
1817
    // Function : privFileDescrParseAtt()
1818
    // Description :
1819
    // Parameters :
1820
    // Return Values :
1821
    //   1 on success.
1822
    //   0 on failure.
1823
    // --------------------------------------------------------------------------------
1824
    public function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options = false)
0 ignored issues
show
Unused Code introduced by
The parameter $v_options is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1824
    public function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, /** @scrutinizer ignore-unused */ $v_options, $v_requested_options = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1825
    {
1826
        $v_result = 1;
1827
1828
        // ----- For each file in the list check the attributes
1829
        foreach ($p_file_list as $v_key => $v_value) {
1830
1831
            // ----- Check if the option is supported
1832
            if (!isset($v_requested_options[$v_key])) {
1833
                // ----- Error log
1834
                PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '" . $v_key . "' for this file");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1834
                PclZip::/** @scrutinizer ignore-call */ 
1835
                        privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '" . $v_key . "' for this file");
Loading history...
1835
1836
                // ----- Return
1837
                return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1837
                return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
1838
            }
1839
1840
            // ----- Look for attribute
1841
            switch ($v_key) {
1842
                case PCLZIP_ATT_FILE_NAME:
1843
                    if (!is_string($v_value)) {
1844
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
1845
1846
                        return PclZip::errorCode();
1847
                    }
1848
1849
                    $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1850
1851
                    if ($p_filedescr['filename'] == '') {
1852
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '" . PclZipUtilOptionText($v_key) . "'");
1853
1854
                        return PclZip::errorCode();
1855
                    }
1856
1857
                    break;
1858
1859
                case PCLZIP_ATT_FILE_NEW_SHORT_NAME:
1860
                    if (!is_string($v_value)) {
1861
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
1862
1863
                        return PclZip::errorCode();
1864
                    }
1865
1866
                    $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1867
1868
                    if ($p_filedescr['new_short_name'] == '') {
1869
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '" . PclZipUtilOptionText($v_key) . "'");
1870
1871
                        return PclZip::errorCode();
1872
                    }
1873
                    break;
1874
1875
                case PCLZIP_ATT_FILE_NEW_FULL_NAME:
1876
                    if (!is_string($v_value)) {
1877
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
1878
1879
                        return PclZip::errorCode();
1880
                    }
1881
1882
                    $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1883
1884
                    if ($p_filedescr['new_full_name'] == '') {
1885
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '" . PclZipUtilOptionText($v_key) . "'");
1886
1887
                        return PclZip::errorCode();
1888
                    }
1889
                    break;
1890
1891
                // ----- Look for options that takes a string
1892
                case PCLZIP_ATT_FILE_COMMENT:
1893
                    if (!is_string($v_value)) {
1894
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
1895
1896
                        return PclZip::errorCode();
1897
                    }
1898
1899
                    $p_filedescr['comment'] = $v_value;
1900
                    break;
1901
1902
                case PCLZIP_ATT_FILE_MTIME:
1903
                    if (!is_integer($v_value)) {
1904
                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". Integer expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
1905
1906
                        return PclZip::errorCode();
1907
                    }
1908
1909
                    $p_filedescr['mtime'] = $v_value;
1910
                    break;
1911
1912
                case PCLZIP_ATT_FILE_CONTENT:
1913
                    $p_filedescr['content'] = $v_value;
1914
                    break;
1915
1916
                default:
1917
                    // ----- Error log
1918
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" . $v_key . "'");
1919
1920
                    // ----- Return
1921
                    return PclZip::errorCode();
1922
            }
1923
1924
            // ----- Look for mandatory options
1925
            if ($v_requested_options !== false) {
1926
                for ($key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $key is dead and can be removed.
Loading history...
1927
                    // ----- Look for mandatory option
1928
                    if ($v_requested_options[$key] == 'mandatory') {
1929
                        // ----- Look if present
1930
                        if (!isset($p_file_list[$key])) {
1931
                            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")");
1932
1933
                            return PclZip::errorCode();
1934
                        }
1935
                    }
1936
                }
1937
            }
1938
1939
            // end foreach
1940
        }
1941
1942
        // ----- Return
1943
        return $v_result;
1944
    }
1945
    // --------------------------------------------------------------------------------
1946
1947
    // --------------------------------------------------------------------------------
1948
    // Function : privFileDescrExpand()
1949
    // Description :
1950
    //   This method look for each item of the list to see if its a file, a folder
1951
    //   or a string to be added as file. For any other type of files (link, other)
1952
    //   just ignore the item.
1953
    //   Then prepare the information that will be stored for that file.
1954
    //   When its a folder, expand the folder with all the files that are in that
1955
    //   folder (recursively).
1956
    // Parameters :
1957
    // Return Values :
1958
    //   1 on success.
1959
    //   0 on failure.
1960
    // --------------------------------------------------------------------------------
1961
    public function privFileDescrExpand(&$p_filedescr_list, &$p_options)
1962
    {
1963
        $v_result = 1;
1964
1965
        // ----- Create a result list
1966
        $v_result_list = array();
1967
1968
        // ----- Look each entry
1969
        for ($i = 0; $i < sizeof($p_filedescr_list); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1970
1971
            // ----- Get filedescr
1972
            $v_descr = $p_filedescr_list[$i];
1973
1974
            // ----- Reduce the filename
1975
            $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
1976
            $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
1977
1978
            // ----- Look for real file or folder
1979
            if (file_exists($v_descr['filename'])) {
1980
                if (@is_file($v_descr['filename'])) {
1981
                    $v_descr['type'] = 'file';
1982
                } elseif (@is_dir($v_descr['filename'])) {
1983
                    $v_descr['type'] = 'folder';
1984
                } elseif (@is_link($v_descr['filename'])) {
1985
                    // skip
1986
                    continue;
1987
                } else {
1988
                    // skip
1989
                    continue;
1990
                }
1991
1992
            // ----- Look for string added as file
1993
            } elseif (isset($v_descr['content'])) {
1994
                $v_descr['type'] = 'virtual_file';
1995
1996
            // ----- Missing file
1997
            } else {
1998
                // ----- Error log
1999
                PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $v_descr['filename'] . "' does not exist");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1999
                PclZip::/** @scrutinizer ignore-call */ 
2000
                        privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $v_descr['filename'] . "' does not exist");
Loading history...
2000
2001
                // ----- Return
2002
                return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2002
                return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
2003
            }
2004
2005
            // ----- Calculate the stored filename
2006
            $this->privCalculateStoredFilename($v_descr, $p_options);
2007
2008
            // ----- Add the descriptor in result list
2009
            $v_result_list[sizeof($v_result_list)] = $v_descr;
2010
2011
            // ----- Look for folder
2012
            if ($v_descr['type'] == 'folder') {
2013
                // ----- List of items in folder
2014
                $v_dirlist_descr = array();
2015
                $v_dirlist_nb    = 0;
2016
                if ($v_folder_handler = @opendir($v_descr['filename'])) {
2017
                    while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2018
2019
                        // ----- Skip '.' and '..'
2020
                        if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2021
                            continue;
2022
                        }
2023
2024
                        // ----- Compose the full filename
2025
                        $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'] . '/' . $v_item_handler;
2026
2027
                        // ----- Look for different stored filename
2028
                        // Because the name of the folder was changed, the name of the
2029
                        // files/sub-folders also change
2030
                        if (($v_descr['stored_filename'] != $v_descr['filename']) && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2031
                            if ($v_descr['stored_filename'] != '') {
2032
                                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'] . '/' . $v_item_handler;
2033
                            } else {
2034
                                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2035
                            }
2036
                        }
2037
2038
                        $v_dirlist_nb++;
2039
                    }
2040
2041
                    @closedir($v_folder_handler);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for closedir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2041
                    /** @scrutinizer ignore-unhandled */ @closedir($v_folder_handler);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
Are you sure the usage of closedir($v_folder_handler) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
2042
                } else {
2043
                    // TBC : unable to open folder in read mode
2044
                }
2045
2046
                // ----- Expand each element of the list
2047
                if ($v_dirlist_nb != 0) {
2048
                    // ----- Expand
2049
                    if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2050
                        return $v_result;
2051
                    }
2052
2053
                    // ----- Concat the resulting list
2054
                    $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2055
                } else {
2056
                }
2057
2058
                // ----- Free local array
2059
                unset($v_dirlist_descr);
2060
            }
2061
        }
2062
2063
        // ----- Get the result list
2064
        $p_filedescr_list = $v_result_list;
2065
2066
        // ----- Return
2067
        return $v_result;
2068
    }
2069
    // --------------------------------------------------------------------------------
2070
2071
    // --------------------------------------------------------------------------------
2072
    // Function : privCreate()
2073
    // Description :
2074
    // Parameters :
2075
    // Return Values :
2076
    // --------------------------------------------------------------------------------
2077
    public function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2078
    {
2079
        $v_result      = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
2080
        $v_list_detail = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $v_list_detail is dead and can be removed.
Loading history...
2081
2082
        // ----- Magic quotes trick
2083
        $this->privDisableMagicQuotes();
2084
2085
        // ----- Open the file in write mode
2086
        if (($v_result = $this->privOpenFd('wb')) != 1) {
2087
            // ----- Return
2088
            return $v_result;
2089
        }
2090
2091
        // ----- Add the list of files
2092
        $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2093
2094
        // ----- Close
2095
        $this->privCloseFd();
2096
2097
        // ----- Magic quotes trick
2098
        $this->privSwapBackMagicQuotes();
2099
2100
        // ----- Return
2101
        return $v_result;
2102
    }
2103
    // --------------------------------------------------------------------------------
2104
2105
    // --------------------------------------------------------------------------------
2106
    // Function : privAdd()
2107
    // Description :
2108
    // Parameters :
2109
    // Return Values :
2110
    // --------------------------------------------------------------------------------
2111
    public function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2112
    {
2113
        $v_result      = 1;
2114
        $v_list_detail = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $v_list_detail is dead and can be removed.
Loading history...
2115
2116
        // ----- Look if the archive exists or is empty
2117
        if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) {
2118
2119
            // ----- Do a create
2120
            $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2121
2122
            // ----- Return
2123
            return $v_result;
2124
        }
2125
        // ----- Magic quotes trick
2126
        $this->privDisableMagicQuotes();
2127
2128
        // ----- Open the zip file
2129
        if (($v_result = $this->privOpenFd('rb')) != 1) {
2130
            // ----- Magic quotes trick
2131
            $this->privSwapBackMagicQuotes();
2132
2133
            // ----- Return
2134
            return $v_result;
2135
        }
2136
2137
        // ----- Read the central directory informations
2138
        $v_central_dir = array();
2139
        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
2140
            $this->privCloseFd();
2141
            $this->privSwapBackMagicQuotes();
2142
2143
            return $v_result;
2144
        }
2145
2146
        // ----- Go to beginning of File
2147
        @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rewind(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2147
        /** @scrutinizer ignore-unhandled */ @rewind($this->zip_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2147
        @rewind(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
2148
2149
        // ----- Creates a temporay file
2150
        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
2151
2152
        // ----- Open the temporary file in write mode
2153
        if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
2154
            $this->privCloseFd();
2155
            $this->privSwapBackMagicQuotes();
2156
2157
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2157
            PclZip::/** @scrutinizer ignore-call */ 
2158
                    privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode');
Loading history...
2158
2159
            // ----- Return
2160
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2160
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
2161
        }
2162
2163
        // ----- Copy the files from the archive to the temporary file
2164
        // TBC : Here I should better append the file and go back to erase the central dir
2165
        $v_size = $v_central_dir['offset'];
2166
        while ($v_size != 0) {
2167
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2168
            $v_buffer    = fread($this->zip_fd, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2168
            $v_buffer    = fread(/** @scrutinizer ignore-type */ $this->zip_fd, $v_read_size);
Loading history...
2169
            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false; however, parameter $stream of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2169
            @fwrite(/** @scrutinizer ignore-type */ $v_zip_temp_fd, $v_buffer, $v_read_size);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2169
            /** @scrutinizer ignore-unhandled */ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2170
            $v_size -= $v_read_size;
2171
        }
2172
2173
        // ----- Swap the file descriptor
2174
        // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2175
        // the following methods on the temporary fil and not the real archive
2176
        $v_swap        = $this->zip_fd;
2177
        $this->zip_fd  = $v_zip_temp_fd;
2178
        $v_zip_temp_fd = $v_swap;
2179
2180
        // ----- Add the files
2181
        $v_header_list = array();
2182
        if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) {
2183
            fclose($v_zip_temp_fd);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false and integer; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2183
            fclose(/** @scrutinizer ignore-type */ $v_zip_temp_fd);
Loading history...
2184
            $this->privCloseFd();
2185
            @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2185
            /** @scrutinizer ignore-unhandled */ @unlink($v_zip_temp_name);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2186
            $this->privSwapBackMagicQuotes();
2187
2188
            // ----- Return
2189
            return $v_result;
2190
        }
2191
2192
        // ----- Store the offset of the central dir
2193
        $v_offset = @ftell($this->zip_fd);
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false; however, parameter $stream of ftell() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2193
        $v_offset = @ftell(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
2194
2195
        // ----- Copy the block of file headers from the old archive
2196
        $v_size = $v_central_dir['size'];
2197
        while ($v_size != 0) {
2198
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2199
            $v_buffer    = @fread($v_zip_temp_fd, $v_read_size);
2200
            @fwrite($this->zip_fd, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2200
            @fwrite($this->zip_fd, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
2201
            $v_size -= $v_read_size;
2202
        }
2203
2204
        // ----- Create the Central Dir files header
2205
        for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
2206
            // ----- Create the file header
2207
            if ($v_header_list[$i]['status'] == 'ok') {
2208
                if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2209
                    fclose($v_zip_temp_fd);
2210
                    $this->privCloseFd();
2211
                    @unlink($v_zip_temp_name);
2212
                    $this->privSwapBackMagicQuotes();
2213
2214
                    // ----- Return
2215
                    return $v_result;
2216
                }
2217
                $v_count++;
2218
            }
2219
2220
            // ----- Transform the header to a 'usable' info
2221
            $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2222
        }
2223
2224
        // ----- Zip file comment
2225
        $v_comment = $v_central_dir['comment'];
2226
        if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2227
            $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2228
        }
2229
        if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2230
            $v_comment = $v_comment . $p_options[PCLZIP_OPT_ADD_COMMENT];
2231
        }
2232
        if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2233
            $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT] . $v_comment;
2234
        }
2235
2236
        // ----- Calculate the size of the central header
2237
        $v_size = @ftell($this->zip_fd) - $v_offset;
2238
2239
        // ----- Create the central dir footer
2240
        if (($v_result = $this->privWriteCentralHeader($v_count + $v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) {
2241
            // ----- Reset the file list
2242
            unset($v_header_list);
2243
            $this->privSwapBackMagicQuotes();
2244
2245
            // ----- Return
2246
            return $v_result;
2247
        }
2248
2249
        // ----- Swap back the file descriptor
2250
        $v_swap        = $this->zip_fd;
2251
        $this->zip_fd  = $v_zip_temp_fd;
2252
        $v_zip_temp_fd = $v_swap;
2253
2254
        // ----- Close
2255
        $this->privCloseFd();
2256
2257
        // ----- Close the temporary file
2258
        @fclose($v_zip_temp_fd);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2258
        @fclose(/** @scrutinizer ignore-type */ $v_zip_temp_fd);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2258
        /** @scrutinizer ignore-unhandled */ @fclose($v_zip_temp_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2259
2260
        // ----- Magic quotes trick
2261
        $this->privSwapBackMagicQuotes();
2262
2263
        // ----- Delete the zip file
2264
        // TBC : I should test the result ...
2265
        @unlink($this->zipname);
2266
2267
        // ----- Rename the temporary file
2268
        // TBC : I should test the result ...
2269
        //@rename($v_zip_temp_name, $this->zipname);
2270
        PclZipUtilRename($v_zip_temp_name, $this->zipname);
2271
2272
        // ----- Return
2273
        return $v_result;
2274
    }
2275
    // --------------------------------------------------------------------------------
2276
2277
    // --------------------------------------------------------------------------------
2278
    // Function : privOpenFd()
2279
    // Description :
2280
    // Parameters :
2281
    // --------------------------------------------------------------------------------
2282
    public function privOpenFd($p_mode)
2283
    {
2284
        $v_result = 1;
2285
2286
        // ----- Look if already open
2287
        if ($this->zip_fd != 0) {
2288
            // ----- Error log
2289
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \'' . $this->zipname . '\' already open');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2289
            PclZip::/** @scrutinizer ignore-call */ 
2290
                    privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \'' . $this->zipname . '\' already open');
Loading history...
2290
2291
            // ----- Return
2292
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2292
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
2293
        }
2294
2295
        // ----- Open the zip file
2296
        if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) {
2297
            // ----- Error log
2298
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in ' . $p_mode . ' mode');
2299
2300
            // ----- Return
2301
            return PclZip::errorCode();
2302
        }
2303
2304
        // ----- Return
2305
        return $v_result;
2306
    }
2307
    // --------------------------------------------------------------------------------
2308
2309
    // --------------------------------------------------------------------------------
2310
    // Function : privCloseFd()
2311
    // Description :
2312
    // Parameters :
2313
    // --------------------------------------------------------------------------------
2314
    public function privCloseFd()
2315
    {
2316
        $v_result = 1;
2317
2318
        if ($this->zip_fd != 0) {
2319
            @fclose($this->zip_fd);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fclose(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2319
            @fclose(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2319
            /** @scrutinizer ignore-unhandled */ @fclose($this->zip_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2320
        }
2321
        $this->zip_fd = 0;
2322
2323
        // ----- Return
2324
        return $v_result;
2325
    }
2326
    // --------------------------------------------------------------------------------
2327
2328
    // --------------------------------------------------------------------------------
2329
    // Function : privAddList()
2330
    // Description :
2331
    //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2332
    //   different from the real path of the file. This is usefull if you want to have PclTar
2333
    //   running in any directory, and memorize relative path from an other directory.
2334
    // Parameters :
2335
    //   $p_list : An array containing the file or directory names to add in the tar
2336
    //   $p_result_list : list of added files with their properties (specially the status field)
2337
    //   $p_add_dir : Path to add in the filename path archived
2338
    //   $p_remove_dir : Path to remove in the filename path archived
2339
    // Return Values :
2340
    // --------------------------------------------------------------------------------
2341
    //  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2342
    public function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2343
    {
2344
        $v_result = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
2345
2346
        // ----- Add the files
2347
        $v_header_list = array();
2348
        if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) {
2349
            // ----- Return
2350
            return $v_result;
2351
        }
2352
2353
        // ----- Store the offset of the central dir
2354
        $v_offset = @ftell($this->zip_fd);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of ftell(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2354
        $v_offset = @ftell(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
2355
2356
        // ----- Create the Central Dir files header
2357
        for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
2358
            // ----- Create the file header
2359
            if ($v_header_list[$i]['status'] == 'ok') {
2360
                if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2361
                    // ----- Return
2362
                    return $v_result;
2363
                }
2364
                $v_count++;
2365
            }
2366
2367
            // ----- Transform the header to a 'usable' info
2368
            $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2369
        }
2370
2371
        // ----- Zip file comment
2372
        $v_comment = '';
2373
        if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2374
            $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2375
        }
2376
2377
        // ----- Calculate the size of the central header
2378
        $v_size = @ftell($this->zip_fd) - $v_offset;
2379
2380
        // ----- Create the central dir footer
2381
        if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) {
2382
            // ----- Reset the file list
2383
            unset($v_header_list);
2384
2385
            // ----- Return
2386
            return $v_result;
2387
        }
2388
2389
        // ----- Return
2390
        return $v_result;
2391
    }
2392
    // --------------------------------------------------------------------------------
2393
2394
    // --------------------------------------------------------------------------------
2395
    // Function : privAddFileList()
2396
    // Description :
2397
    // Parameters :
2398
    //   $p_filedescr_list : An array containing the file description
2399
    //                      or directory names to add in the zip
2400
    //   $p_result_list : list of added files with their properties (specially the status field)
2401
    // Return Values :
2402
    // --------------------------------------------------------------------------------
2403
    public function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2404
    {
2405
        $v_result = 1;
2406
        $v_header = array();
2407
2408
        // ----- Recuperate the current number of elt in list
2409
        $v_nb = sizeof($p_result_list);
2410
2411
        // ----- Loop on the files
2412
        for ($j = 0; ($j < sizeof($p_filedescr_list)) && ($v_result == 1); $j++) {
2413
            // ----- Format the filename
2414
            $p_filedescr_list[$j]['filename'] = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2415
2416
            // ----- Skip empty file names
2417
            // TBC : Can this be possible ? not checked in DescrParseAtt ?
2418
            if ($p_filedescr_list[$j]['filename'] == "") {
2419
                continue;
2420
            }
2421
2422
            // ----- Check the filename
2423
            if (($p_filedescr_list[$j]['type'] != 'virtual_file') && (!file_exists($p_filedescr_list[$j]['filename']))) {
2424
                PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $p_filedescr_list[$j]['filename'] . "' does not exist");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2424
                PclZip::/** @scrutinizer ignore-call */ 
2425
                        privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $p_filedescr_list[$j]['filename'] . "' does not exist");
Loading history...
2425
2426
                return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2426
                return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
2427
            }
2428
2429
            // ----- Look if it is a file or a dir with no all path remove option
2430
            // or a dir with all its path removed
2431
            //      if (   (is_file($p_filedescr_list[$j]['filename']))
2432
            //          || (   is_dir($p_filedescr_list[$j]['filename'])
2433
            if (($p_filedescr_list[$j]['type'] == 'file') || ($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]))) {
2434
2435
                // ----- Add the file
2436
                $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, $p_options);
2437
                if ($v_result != 1) {
2438
                    return $v_result;
2439
                }
2440
2441
                // ----- Store the file infos
2442
                $p_result_list[$v_nb++] = $v_header;
2443
            }
2444
        }
2445
2446
        // ----- Return
2447
        return $v_result;
2448
    }
2449
    // --------------------------------------------------------------------------------
2450
2451
    // --------------------------------------------------------------------------------
2452
    // Function : privAddFile()
2453
    // Description :
2454
    // Parameters :
2455
    // Return Values :
2456
    // --------------------------------------------------------------------------------
2457
    public function privAddFile($p_filedescr, &$p_header, &$p_options)
2458
    {
2459
        $v_result = 1;
2460
2461
        // ----- Working variable
2462
        $p_filename = $p_filedescr['filename'];
2463
2464
        // TBC : Already done in the fileAtt check ... ?
2465
        if ($p_filename == "") {
2466
            // ----- Error log
2467
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2467
            PclZip::/** @scrutinizer ignore-call */ 
2468
                    privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
Loading history...
2468
2469
            // ----- Return
2470
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2470
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
2471
        }
2472
2473
        // ----- Look for a stored different filename
2474
        /* TBC : Removed
2475
        if (isset($p_filedescr['stored_filename'])) {
2476
        $v_stored_filename = $p_filedescr['stored_filename'];
2477
        } else {
2478
        $v_stored_filename = $p_filedescr['stored_filename'];
2479
        }
2480
        */
2481
2482
        // ----- Set the file properties
2483
        clearstatcache();
2484
        $p_header['version']           = 20;
2485
        $p_header['version_extracted'] = 10;
2486
        $p_header['flag']              = 0;
2487
        $p_header['compression']       = 0;
2488
        $p_header['crc']               = 0;
2489
        $p_header['compressed_size']   = 0;
2490
        $p_header['filename_len']      = strlen($p_filename);
2491
        $p_header['extra_len']         = 0;
2492
        $p_header['disk']              = 0;
2493
        $p_header['internal']          = 0;
2494
        $p_header['offset']            = 0;
2495
        $p_header['filename']          = $p_filename;
2496
        // TBC : Removed    $p_header['stored_filename'] = $v_stored_filename;
2497
        $p_header['stored_filename']   = $p_filedescr['stored_filename'];
2498
        $p_header['extra']             = '';
2499
        $p_header['status']            = 'ok';
2500
        $p_header['index']             = -1;
2501
2502
        // ----- Look for regular file
2503
        if ($p_filedescr['type'] == 'file') {
2504
            $p_header['external'] = 0x00000000;
2505
            $p_header['size']     = filesize($p_filename);
2506
2507
        // ----- Look for regular folder
2508
        } elseif ($p_filedescr['type'] == 'folder') {
2509
            $p_header['external'] = 0x00000010;
2510
            $p_header['mtime']    = filemtime($p_filename);
2511
            $p_header['size']     = filesize($p_filename);
2512
2513
        // ----- Look for virtual file
2514
        } elseif ($p_filedescr['type'] == 'virtual_file') {
2515
            $p_header['external'] = 0x00000000;
2516
            $p_header['size']     = strlen($p_filedescr['content']);
2517
        }
2518
2519
        // ----- Look for filetime
2520
        if (isset($p_filedescr['mtime'])) {
2521
            $p_header['mtime'] = $p_filedescr['mtime'];
2522
        } elseif ($p_filedescr['type'] == 'virtual_file') {
2523
            $p_header['mtime'] = time();
2524
        } else {
2525
            $p_header['mtime'] = filemtime($p_filename);
2526
        }
2527
2528
        // ------ Look for file comment
2529
        if (isset($p_filedescr['comment'])) {
2530
            $p_header['comment_len'] = strlen($p_filedescr['comment']);
2531
            $p_header['comment']     = $p_filedescr['comment'];
2532
        } else {
2533
            $p_header['comment_len'] = 0;
2534
            $p_header['comment']     = '';
2535
        }
2536
2537
        // ----- Look for pre-add callback
2538
        if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2539
2540
            // ----- Generate a local information
2541
            $v_local_header = array();
2542
            $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2543
2544
            // ----- Call the callback
2545
            // Here I do not use call_user_func() because I need to send a reference to the
2546
            // header.
2547
            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2548
            $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2549
            if ($v_result == 0) {
2550
                // ----- Change the file status
2551
                $p_header['status'] = "skipped";
2552
                $v_result           = 1;
2553
            }
2554
2555
            // ----- Update the informations
2556
            // Only some fields can be modified
2557
            if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2558
                $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2559
            }
2560
        }
2561
2562
        // ----- Look for empty stored filename
2563
        if ($p_header['stored_filename'] == "") {
2564
            $p_header['status'] = "filtered";
2565
        }
2566
2567
        // ----- Check the path length
2568
        if (strlen($p_header['stored_filename']) > 0xFF) {
2569
            $p_header['status'] = 'filename_too_long';
2570
        }
2571
2572
        // ----- Look if no error, or file not skipped
2573
        if ($p_header['status'] == 'ok') {
2574
2575
            // ----- Look for a file
2576
            if ($p_filedescr['type'] == 'file') {
2577
                // ----- Look for using temporary file to zip
2578
                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'])))) {
2579
                    $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2580
                    if ($v_result < PCLZIP_ERR_NO_ERROR) {
2581
                        return $v_result;
2582
                    }
2583
2584
                // ----- Use "in memory" zip algo
2585
                } else {
2586
2587
                    // ----- Open the source file
2588
                    if (($v_file = @fopen($p_filename, "rb")) == 0) {
2589
                        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2590
2591
                        return PclZip::errorCode();
2592
                    }
2593
2594
                    // ----- Read the file content
2595
                    $v_content = @fread($v_file, $p_header['size']);
0 ignored issues
show
Bug introduced by
It seems like $v_file can also be of type false; however, parameter $stream of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2595
                    $v_content = @fread(/** @scrutinizer ignore-type */ $v_file, $p_header['size']);
Loading history...
2596
2597
                    // ----- Close the file
2598
                    @fclose($v_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2598
                    /** @scrutinizer ignore-unhandled */ @fclose($v_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_file can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2598
                    @fclose(/** @scrutinizer ignore-type */ $v_file);
Loading history...
2599
2600
                    // ----- Calculate the CRC
2601
                    $p_header['crc'] = @crc32($v_content);
0 ignored issues
show
Bug introduced by
It seems like $v_content can also be of type false; however, parameter $string of crc32() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2601
                    $p_header['crc'] = @crc32(/** @scrutinizer ignore-type */ $v_content);
Loading history...
2602
2603
                    // ----- Look for no compression
2604
                    if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2605
                        // ----- Set header parameters
2606
                        $p_header['compressed_size'] = $p_header['size'];
2607
                        $p_header['compression']     = 0;
2608
2609
                    // ----- Look for normal compression
2610
                    } else {
2611
                        // ----- Compress the content
2612
                        $v_content = @gzdeflate($v_content);
0 ignored issues
show
Bug introduced by
It seems like $v_content can also be of type false; however, parameter $data of gzdeflate() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2612
                        $v_content = @gzdeflate(/** @scrutinizer ignore-type */ $v_content);
Loading history...
2613
2614
                        // ----- Set header parameters
2615
                        $p_header['compressed_size'] = strlen($v_content);
0 ignored issues
show
Bug introduced by
It seems like $v_content can also be of type false; however, parameter $string of strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2615
                        $p_header['compressed_size'] = strlen(/** @scrutinizer ignore-type */ $v_content);
Loading history...
2616
                        $p_header['compression']     = 8;
2617
                    }
2618
2619
                    // ----- Call the header generation
2620
                    if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2621
                        @fclose($v_file);
2622
2623
                        return $v_result;
2624
                    }
2625
2626
                    // ----- Write the compressed (or not) content
2627
                    @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fwrite(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2627
                    @fwrite(/** @scrutinizer ignore-type */ $this->zip_fd, $v_content, $p_header['compressed_size']);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2627
                    /** @scrutinizer ignore-unhandled */ @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_content can also be of type false; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2627
                    @fwrite($this->zip_fd, /** @scrutinizer ignore-type */ $v_content, $p_header['compressed_size']);
Loading history...
2628
2629
                }
2630
2631
            // ----- Look for a virtual file (a file from string)
2632
            } elseif ($p_filedescr['type'] == 'virtual_file') {
2633
2634
                $v_content = $p_filedescr['content'];
2635
2636
                // ----- Calculate the CRC
2637
                $p_header['crc'] = @crc32($v_content);
2638
2639
                // ----- Look for no compression
2640
                if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2641
                    // ----- Set header parameters
2642
                    $p_header['compressed_size'] = $p_header['size'];
2643
                    $p_header['compression']     = 0;
2644
2645
                // ----- Look for normal compression
2646
                } else {
2647
                    // ----- Compress the content
2648
                    $v_content = @gzdeflate($v_content);
2649
2650
                    // ----- Set header parameters
2651
                    $p_header['compressed_size'] = strlen($v_content);
2652
                    $p_header['compression']     = 8;
2653
                }
2654
2655
                // ----- Call the header generation
2656
                if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2657
                    @fclose($v_file);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $v_file seems to be never defined.
Loading history...
2658
2659
                    return $v_result;
2660
                }
2661
2662
                // ----- Write the compressed (or not) content
2663
                @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2664
2665
            // ----- Look for a directory
2666
            } elseif ($p_filedescr['type'] == 'folder') {
2667
                // ----- Look for directory last '/'
2668
                if (@substr($p_header['stored_filename'], -1) != '/') {
2669
                    $p_header['stored_filename'] .= '/';
2670
                }
2671
2672
                // ----- Set the file properties
2673
                $p_header['size']     = 0;
2674
                //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
2675
                $p_header['external'] = 0x00000010; // Value for a folder : to be checked
2676
2677
                // ----- Call the header generation
2678
                if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2679
                    return $v_result;
2680
                }
2681
            }
2682
        }
2683
2684
        // ----- Look for post-add callback
2685
        if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2686
2687
            // ----- Generate a local information
2688
            $v_local_header = array();
2689
            $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2690
2691
            // ----- Call the callback
2692
            // Here I do not use call_user_func() because I need to send a reference to the
2693
            // header.
2694
            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2695
            $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2696
            if ($v_result == 0) {
2697
                // ----- Ignored
2698
                $v_result = 1;
2699
            }
2700
2701
            // ----- Update the informations
2702
            // Nothing can be modified
2703
        }
2704
2705
        // ----- Return
2706
        return $v_result;
2707
    }
2708
    // --------------------------------------------------------------------------------
2709
2710
    // --------------------------------------------------------------------------------
2711
    // Function : privAddFileUsingTempFile()
2712
    // Description :
2713
    // Parameters :
2714
    // Return Values :
2715
    // --------------------------------------------------------------------------------
2716
    public function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
0 ignored issues
show
Unused Code introduced by
The parameter $p_options is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

2716
    public function privAddFileUsingTempFile($p_filedescr, &$p_header, /** @scrutinizer ignore-unused */ &$p_options)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2717
    {
2718
        $v_result = PCLZIP_ERR_NO_ERROR;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
2719
2720
        // ----- Working variable
2721
        $p_filename = $p_filedescr['filename'];
2722
2723
        // ----- Open the source file
2724
        if (($v_file = @fopen($p_filename, "rb")) == 0) {
2725
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2725
            PclZip::/** @scrutinizer ignore-call */ 
2726
                    privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
Loading history...
2726
2727
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2727
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
2728
        }
2729
2730
        // ----- Creates a compressed temporary file
2731
        $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz';
2732
        if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2733
            fclose($v_file);
0 ignored issues
show
Bug introduced by
It seems like $v_file can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2733
            fclose(/** @scrutinizer ignore-type */ $v_file);
Loading history...
2734
            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode');
2735
2736
            return PclZip::errorCode();
2737
        }
2738
2739
        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2740
        $v_size = filesize($p_filename);
2741
        while ($v_size != 0) {
2742
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2743
            $v_buffer    = @fread($v_file, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_file can also be of type false; however, parameter $stream of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2743
            $v_buffer    = @fread(/** @scrutinizer ignore-type */ $v_file, $v_read_size);
Loading history...
2744
            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2745
            @gzputs($v_file_compressed, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of gzputs() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2745
            @gzputs($v_file_compressed, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for gzputs(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2745
            /** @scrutinizer ignore-unhandled */ @gzputs($v_file_compressed, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_file_compressed can also be of type false; however, parameter $stream of gzputs() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2745
            @gzputs(/** @scrutinizer ignore-type */ $v_file_compressed, $v_buffer, $v_read_size);
Loading history...
2746
            $v_size -= $v_read_size;
2747
        }
2748
2749
        // ----- Close the file
2750
        @fclose($v_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2750
        /** @scrutinizer ignore-unhandled */ @fclose($v_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2751
        @gzclose($v_file_compressed);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for gzclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2751
        /** @scrutinizer ignore-unhandled */ @gzclose($v_file_compressed);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_file_compressed can also be of type false; however, parameter $stream of gzclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2751
        @gzclose(/** @scrutinizer ignore-type */ $v_file_compressed);
Loading history...
2752
2753
        // ----- Check the minimum file size
2754
        if (filesize($v_gzip_temp_name) < 18) {
2755
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \'' . $v_gzip_temp_name . '\' has invalid filesize - should be minimum 18 bytes');
2756
2757
            return PclZip::errorCode();
2758
        }
2759
2760
        // ----- Extract the compressed attributes
2761
        if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2762
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode');
2763
2764
            return PclZip::errorCode();
2765
        }
2766
2767
        // ----- Read the gzip file header
2768
        $v_binary_data = @fread($v_file_compressed, 10);
2769
        $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
0 ignored issues
show
Bug introduced by
It seems like $v_binary_data can also be of type false; however, parameter $string of unpack() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2769
        $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', /** @scrutinizer ignore-type */ $v_binary_data);
Loading history...
2770
2771
        // ----- Check some parameters
2772
        $v_data_header['os'] = bin2hex($v_data_header['os']);
2773
2774
        // ----- Read the gzip file footer
2775
        @fseek($v_file_compressed, filesize($v_gzip_temp_name) - 8);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fseek(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2775
        /** @scrutinizer ignore-unhandled */ @fseek($v_file_compressed, filesize($v_gzip_temp_name) - 8);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_file_compressed can also be of type false; however, parameter $stream of fseek() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2775
        @fseek(/** @scrutinizer ignore-type */ $v_file_compressed, filesize($v_gzip_temp_name) - 8);
Loading history...
2776
        $v_binary_data = @fread($v_file_compressed, 8);
2777
        $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2778
2779
        // ----- Set the attributes
2780
        $p_header['compression']     = ord($v_data_header['cm']);
2781
        //$p_header['mtime'] = $v_data_header['mtime'];
2782
        $p_header['crc']             = $v_data_footer['crc'];
2783
        $p_header['compressed_size'] = filesize($v_gzip_temp_name) - 18;
2784
2785
        // ----- Close the file
2786
        @fclose($v_file_compressed);
2787
2788
        // ----- Call the header generation
2789
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2790
            return $v_result;
2791
        }
2792
2793
        // ----- Add the compressed data
2794
        if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2795
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode');
2796
2797
            return PclZip::errorCode();
2798
        }
2799
2800
        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2801
        fseek($v_file_compressed, 10);
2802
        $v_size = $p_header['compressed_size'];
2803
        while ($v_size != 0) {
2804
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2805
            $v_buffer    = @fread($v_file_compressed, $v_read_size);
2806
            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2807
            @fwrite($this->zip_fd, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fwrite(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2807
            @fwrite(/** @scrutinizer ignore-type */ $this->zip_fd, $v_buffer, $v_read_size);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2807
            /** @scrutinizer ignore-unhandled */ @fwrite($this->zip_fd, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2807
            @fwrite($this->zip_fd, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
2808
            $v_size -= $v_read_size;
2809
        }
2810
2811
        // ----- Close the file
2812
        @fclose($v_file_compressed);
2813
2814
        // ----- Unlink the temporary file
2815
        @unlink($v_gzip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2815
        /** @scrutinizer ignore-unhandled */ @unlink($v_gzip_temp_name);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2816
2817
        // ----- Return
2818
        return $v_result;
2819
    }
2820
    // --------------------------------------------------------------------------------
2821
2822
    // --------------------------------------------------------------------------------
2823
    // Function : privCalculateStoredFilename()
2824
    // Description :
2825
    //   Based on file descriptor properties and global options, this method
2826
    //   calculate the filename that will be stored in the archive.
2827
    // Parameters :
2828
    // Return Values :
2829
    // --------------------------------------------------------------------------------
2830
    public function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2831
    {
2832
        $v_result = 1;
2833
2834
        // ----- Working variables
2835
        $p_filename = $p_filedescr['filename'];
2836
        if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2837
            $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2838
        } else {
2839
            $p_add_dir = '';
2840
        }
2841
        if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2842
            $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2843
        } else {
2844
            $p_remove_dir = '';
2845
        }
2846
        if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2847
            $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2848
        } else {
2849
            $p_remove_all_dir = 0;
2850
        }
2851
2852
        // ----- Look for full name change
2853
        if (isset($p_filedescr['new_full_name'])) {
2854
            // ----- Remove drive letter if any
2855
            $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2856
2857
        // ----- Look for path and/or short name change
2858
        } else {
2859
2860
            // ----- Look for short name change
2861
            // Its when we cahnge just the filename but not the path
2862
            if (isset($p_filedescr['new_short_name'])) {
2863
                $v_path_info = pathinfo($p_filename);
2864
                $v_dir       = '';
2865
                if ($v_path_info['dirname'] != '') {
2866
                    $v_dir = $v_path_info['dirname'] . '/';
2867
                }
2868
                $v_stored_filename = $v_dir . $p_filedescr['new_short_name'];
2869
            } else {
2870
                // ----- Calculate the stored filename
2871
                $v_stored_filename = $p_filename;
2872
            }
2873
2874
            // ----- Look for all path to remove
2875
            if ($p_remove_all_dir) {
2876
                $v_stored_filename = basename($p_filename);
2877
2878
            // ----- Look for partial path remove
2879
            } elseif ($p_remove_dir != "") {
2880
                if (substr($p_remove_dir, -1) != '/') {
2881
                    $p_remove_dir .= "/";
2882
                }
2883
2884
                if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) {
2885
2886
                    if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) {
2887
                        $p_remove_dir = "./" . $p_remove_dir;
2888
                    }
2889
                    if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) {
2890
                        $p_remove_dir = substr($p_remove_dir, 2);
2891
                    }
2892
                }
2893
2894
                $v_compare = PclZipUtilPathInclusion($p_remove_dir, $v_stored_filename);
2895
                if ($v_compare > 0) {
2896
                    if ($v_compare == 2) {
2897
                        $v_stored_filename = "";
2898
                    } else {
2899
                        $v_stored_filename = substr($v_stored_filename, strlen($p_remove_dir));
2900
                    }
2901
                }
2902
            }
2903
2904
            // ----- Remove drive letter if any
2905
            $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
2906
2907
            // ----- Look for path to add
2908
            if ($p_add_dir != "") {
2909
                if (substr($p_add_dir, -1) == "/") {
2910
                    $v_stored_filename = $p_add_dir . $v_stored_filename;
2911
                } else {
2912
                    $v_stored_filename = $p_add_dir . "/" . $v_stored_filename;
2913
                }
2914
            }
2915
        }
2916
2917
        // ----- Filename (reduce the path of stored name)
2918
        $v_stored_filename              = PclZipUtilPathReduction($v_stored_filename);
2919
        $p_filedescr['stored_filename'] = $v_stored_filename;
2920
2921
        // ----- Return
2922
        return $v_result;
2923
    }
2924
    // --------------------------------------------------------------------------------
2925
2926
    // --------------------------------------------------------------------------------
2927
    // Function : privWriteFileHeader()
2928
    // Description :
2929
    // Parameters :
2930
    // Return Values :
2931
    // --------------------------------------------------------------------------------
2932
    public function privWriteFileHeader(&$p_header)
2933
    {
2934
        $v_result = 1;
2935
2936
        // ----- Store the offset position of the file
2937
        $p_header['offset'] = ftell($this->zip_fd);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of ftell(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2937
        $p_header['offset'] = ftell(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
2938
2939
        // ----- Transform UNIX mtime to DOS format mdate/mtime
2940
        $v_date  = getdate($p_header['mtime']);
2941
        $v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2;
2942
        $v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday'];
2943
2944
        // ----- Packed data
2945
        $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len']);
2946
2947
        // ----- Write the first 148 bytes of the header in the archive
2948
        fputs($this->zip_fd, $v_binary_data, 30);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fputs(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2948
        fputs(/** @scrutinizer ignore-type */ $this->zip_fd, $v_binary_data, 30);
Loading history...
2949
2950
        // ----- Write the variable fields
2951
        if (strlen($p_header['stored_filename']) != 0) {
2952
            fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2953
        }
2954
        if ($p_header['extra_len'] != 0) {
2955
            fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2956
        }
2957
2958
        // ----- Return
2959
        return $v_result;
2960
    }
2961
    // --------------------------------------------------------------------------------
2962
2963
    // --------------------------------------------------------------------------------
2964
    // Function : privWriteCentralFileHeader()
2965
    // Description :
2966
    // Parameters :
2967
    // Return Values :
2968
    // --------------------------------------------------------------------------------
2969
    public function privWriteCentralFileHeader(&$p_header)
2970
    {
2971
        $v_result = 1;
2972
2973
        // TBC
2974
        //for (reset($p_header); $key = key($p_header); next($p_header)) {
2975
        //}
2976
2977
        // ----- Transform UNIX mtime to DOS format mdate/mtime
2978
        $v_date  = getdate($p_header['mtime']);
2979
        $v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2;
2980
        $v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday'];
2981
2982
        // ----- Packed data
2983
        $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'], $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']);
2984
2985
        // ----- Write the 42 bytes of the header in the zip file
2986
        fputs($this->zip_fd, $v_binary_data, 46);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fputs(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2986
        fputs(/** @scrutinizer ignore-type */ $this->zip_fd, $v_binary_data, 46);
Loading history...
2987
2988
        // ----- Write the variable fields
2989
        if (strlen($p_header['stored_filename']) != 0) {
2990
            fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2991
        }
2992
        if ($p_header['extra_len'] != 0) {
2993
            fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2994
        }
2995
        if ($p_header['comment_len'] != 0) {
2996
            fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
2997
        }
2998
2999
        // ----- Return
3000
        return $v_result;
3001
    }
3002
    // --------------------------------------------------------------------------------
3003
3004
    // --------------------------------------------------------------------------------
3005
    // Function : privWriteCentralHeader()
3006
    // Description :
3007
    // Parameters :
3008
    // Return Values :
3009
    // --------------------------------------------------------------------------------
3010
    public function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3011
    {
3012
        $v_result = 1;
3013
3014
        // ----- Packed data
3015
        $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment));
3016
3017
        // ----- Write the 22 bytes of the header in the zip file
3018
        fputs($this->zip_fd, $v_binary_data, 22);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fputs(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3018
        fputs(/** @scrutinizer ignore-type */ $this->zip_fd, $v_binary_data, 22);
Loading history...
3019
3020
        // ----- Write the variable fields
3021
        if (strlen($p_comment) != 0) {
3022
            fputs($this->zip_fd, $p_comment, strlen($p_comment));
3023
        }
3024
3025
        // ----- Return
3026
        return $v_result;
3027
    }
3028
    // --------------------------------------------------------------------------------
3029
3030
    // --------------------------------------------------------------------------------
3031
    // Function : privList()
3032
    // Description :
3033
    // Parameters :
3034
    // Return Values :
3035
    // --------------------------------------------------------------------------------
3036
    public function privList(&$p_list)
3037
    {
3038
        $v_result = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
3039
3040
        // ----- Magic quotes trick
3041
        $this->privDisableMagicQuotes();
3042
3043
        // ----- Open the zip file
3044
        if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) {
3045
            // ----- Magic quotes trick
3046
            $this->privSwapBackMagicQuotes();
3047
3048
            // ----- Error log
3049
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3049
            PclZip::/** @scrutinizer ignore-call */ 
3050
                    privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode');
Loading history...
3050
3051
            // ----- Return
3052
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3052
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
3053
        }
3054
3055
        // ----- Read the central directory informations
3056
        $v_central_dir = array();
3057
        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
3058
            $this->privSwapBackMagicQuotes();
3059
3060
            return $v_result;
3061
        }
3062
3063
        // ----- Go to beginning of Central Dir
3064
        @rewind($this->zip_fd);
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false; however, parameter $stream of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3064
        @rewind(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for rewind(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3064
        /** @scrutinizer ignore-unhandled */ @rewind($this->zip_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3065
        if (@fseek($this->zip_fd, $v_central_dir['offset'])) {
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false; however, parameter $stream of fseek() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3065
        if (@fseek(/** @scrutinizer ignore-type */ $this->zip_fd, $v_central_dir['offset'])) {
Loading history...
3066
            $this->privSwapBackMagicQuotes();
3067
3068
            // ----- Error log
3069
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3070
3071
            // ----- Return
3072
            return PclZip::errorCode();
3073
        }
3074
3075
        // ----- Read each entry
3076
        for ($i = 0; $i < $v_central_dir['entries']; $i++) {
3077
            // ----- Read the file header
3078
            if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) {
3079
                $this->privSwapBackMagicQuotes();
3080
3081
                return $v_result;
3082
            }
3083
            $v_header['index'] = $i;
3084
3085
            // ----- Get the only interesting attributes
3086
            $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3087
            unset($v_header);
3088
        }
3089
3090
        // ----- Close the zip file
3091
        $this->privCloseFd();
3092
3093
        // ----- Magic quotes trick
3094
        $this->privSwapBackMagicQuotes();
3095
3096
        // ----- Return
3097
        return $v_result;
3098
    }
3099
    // --------------------------------------------------------------------------------
3100
3101
    // --------------------------------------------------------------------------------
3102
    // Function : privConvertHeader2FileInfo()
3103
    // Description :
3104
    //   This function takes the file informations from the central directory
3105
    //   entries and extract the interesting parameters that will be given back.
3106
    //   The resulting file infos are set in the array $p_info
3107
    //     $p_info['filename'] : Filename with full path. Given by user (add),
3108
    //                           extracted in the filesystem (extract).
3109
    //     $p_info['stored_filename'] : Stored filename in the archive.
3110
    //     $p_info['size'] = Size of the file.
3111
    //     $p_info['compressed_size'] = Compressed size of the file.
3112
    //     $p_info['mtime'] = Last modification date of the file.
3113
    //     $p_info['comment'] = Comment associated with the file.
3114
    //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3115
    //     $p_info['status'] = status of the action on the file.
3116
    //     $p_info['crc'] = CRC of the file content.
3117
    // Parameters :
3118
    // Return Values :
3119
    // --------------------------------------------------------------------------------
3120
    public function privConvertHeader2FileInfo($p_header, &$p_info)
3121
    {
3122
        $v_result = 1;
3123
3124
        // ----- Get the interesting attributes
3125
        $v_temp_path               = PclZipUtilPathReduction($p_header['filename']);
3126
        $p_info['filename']        = $v_temp_path;
3127
        $v_temp_path               = PclZipUtilPathReduction($p_header['stored_filename']);
3128
        $p_info['stored_filename'] = $v_temp_path;
3129
        $p_info['size']            = $p_header['size'];
3130
        $p_info['compressed_size'] = $p_header['compressed_size'];
3131
        $p_info['mtime']           = $p_header['mtime'];
3132
        $p_info['comment']         = $p_header['comment'];
3133
        $p_info['folder']          = (($p_header['external'] & 0x00000010) == 0x00000010);
3134
        $p_info['index']           = $p_header['index'];
3135
        $p_info['status']          = $p_header['status'];
3136
        $p_info['crc']             = $p_header['crc'];
3137
3138
        // ----- Return
3139
        return $v_result;
3140
    }
3141
    // --------------------------------------------------------------------------------
3142
3143
    // --------------------------------------------------------------------------------
3144
    // Function : privExtractByRule()
3145
    // Description :
3146
    //   Extract a file or directory depending of rules (by index, by name, ...)
3147
    // Parameters :
3148
    //   $p_file_list : An array where will be placed the properties of each
3149
    //                  extracted file
3150
    //   $p_path : Path to add while writing the extracted files
3151
    //   $p_remove_path : Path to remove (from the file memorized path) while writing the
3152
    //                    extracted files. If the path does not match the file path,
3153
    //                    the file is extracted with its memorized path.
3154
    //                    $p_remove_path does not apply to 'list' mode.
3155
    //                    $p_path and $p_remove_path are commulative.
3156
    // Return Values :
3157
    //   1 on success,0 or less on error (see error code list)
3158
    // --------------------------------------------------------------------------------
3159
    public function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3160
    {
3161
        $v_result = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
3162
3163
        // ----- Magic quotes trick
3164
        $this->privDisableMagicQuotes();
3165
3166
        // ----- Check the path
3167
        if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 1, 2) != ":/"))) {
3168
            $p_path = "./" . $p_path;
3169
        }
3170
3171
        // ----- Reduce the path last (and duplicated) '/'
3172
        if (($p_path != "./") && ($p_path != "/")) {
3173
            // ----- Look for the path end '/'
3174
            while (substr($p_path, -1) == "/") {
3175
                $p_path = substr($p_path, 0, strlen($p_path) - 1);
3176
            }
3177
        }
3178
3179
        // ----- Look for path to remove format (should end by /)
3180
        if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) {
3181
            $p_remove_path .= '/';
3182
        }
3183
        $p_remove_path_size = strlen($p_remove_path);
0 ignored issues
show
Unused Code introduced by
The assignment to $p_remove_path_size is dead and can be removed.
Loading history...
3184
3185
        // ----- Open the zip file
3186
        if (($v_result = $this->privOpenFd('rb')) != 1) {
3187
            $this->privSwapBackMagicQuotes();
3188
3189
            return $v_result;
3190
        }
3191
3192
        // ----- Read the central directory informations
3193
        $v_central_dir = array();
3194
        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
3195
            // ----- Close the zip file
3196
            $this->privCloseFd();
3197
            $this->privSwapBackMagicQuotes();
3198
3199
            return $v_result;
3200
        }
3201
3202
        // ----- Start at beginning of Central Dir
3203
        $v_pos_entry = $v_central_dir['offset'];
3204
3205
        // ----- Read each entry
3206
        $j_start = 0;
3207
        for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {
3208
3209
            // ----- Read next Central dir entry
3210
            @rewind($this->zip_fd);
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3210
            @rewind(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for rewind(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3210
            /** @scrutinizer ignore-unhandled */ @rewind($this->zip_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3211
            if (@fseek($this->zip_fd, $v_pos_entry)) {
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of fseek() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3211
            if (@fseek(/** @scrutinizer ignore-type */ $this->zip_fd, $v_pos_entry)) {
Loading history...
3212
                // ----- Close the zip file
3213
                $this->privCloseFd();
3214
                $this->privSwapBackMagicQuotes();
3215
3216
                // ----- Error log
3217
                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3217
                PclZip::/** @scrutinizer ignore-call */ 
3218
                        privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
Loading history...
3218
3219
                // ----- Return
3220
                return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3220
                return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
3221
            }
3222
3223
            // ----- Read the file header
3224
            $v_header = array();
3225
            if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) {
3226
                // ----- Close the zip file
3227
                $this->privCloseFd();
3228
                $this->privSwapBackMagicQuotes();
3229
3230
                return $v_result;
3231
            }
3232
3233
            // ----- Store the index
3234
            $v_header['index'] = $i;
3235
3236
            // ----- Store the file position
3237
            $v_pos_entry = ftell($this->zip_fd);
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of ftell() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3237
            $v_pos_entry = ftell(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
3238
3239
            // ----- Look for the specific extract rules
3240
            $v_extract = false;
3241
3242
            // ----- Look for extract by name rule
3243
            if ((isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3244
3245
                // ----- Look if the filename is in the list
3246
                for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3247
3248
                    // ----- Look for a directory
3249
                    if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3250
3251
                        // ----- Look if the directory is in the filename path
3252
                        if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3253
                            $v_extract = true;
3254
                        }
3255
3256
                    // ----- Look for a filename
3257
                    } elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3258
                        $v_extract = true;
3259
                    }
3260
                }
3261
            // ----- Look for extract by ereg rule
3262
            // ereg() is deprecated with PHP 5.3
3263
            /*
3264
            elseif (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
3265
            && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3266
3267
            if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3268
            $v_extract = true;
3269
            }
3270
            }
3271
            */
3272
3273
            // ----- Look for extract by preg rule
3274
            } elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3275
3276
                if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3277
                    $v_extract = true;
3278
                }
3279
3280
            // ----- Look for extract by index rule
3281
            } elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3282
3283
                // ----- Look if the index is in the list
3284
                for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3285
3286
                    if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3287
                        $v_extract = true;
3288
                    }
3289
                    if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3290
                        $j_start = $j + 1;
3291
                    }
3292
3293
                    if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) {
3294
                        break;
3295
                    }
3296
                }
3297
3298
            // ----- Look for no rule, which means extract all the archive
3299
            } else {
3300
                $v_extract = true;
3301
            }
3302
3303
            // ----- Check compression method
3304
            if (($v_extract) && (($v_header['compression'] != 8) && ($v_header['compression'] != 0))) {
3305
                $v_header['status'] = 'unsupported_compression';
3306
3307
                // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3308
                if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
3309
3310
                    $this->privSwapBackMagicQuotes();
3311
3312
                    PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, "Filename '" . $v_header['stored_filename'] . "' is " . "compressed by an unsupported compression " . "method (" . $v_header['compression'] . ") ");
3313
3314
                    return PclZip::errorCode();
3315
                }
3316
            }
3317
3318
            // ----- Check encrypted files
3319
            if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3320
                $v_header['status'] = 'unsupported_encryption';
3321
3322
                // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3323
                if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
3324
3325
                    $this->privSwapBackMagicQuotes();
3326
3327
                    PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, "Unsupported encryption for " . " filename '" . $v_header['stored_filename'] . "'");
3328
3329
                    return PclZip::errorCode();
3330
                }
3331
            }
3332
3333
            // ----- Look for real extraction
3334
            if (($v_extract) && ($v_header['status'] != 'ok')) {
3335
                $v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++]);
3336
                if ($v_result != 1) {
3337
                    $this->privCloseFd();
3338
                    $this->privSwapBackMagicQuotes();
3339
3340
                    return $v_result;
3341
                }
3342
3343
                $v_extract = false;
3344
            }
3345
3346
            // ----- Look for real extraction
3347
            if ($v_extract) {
3348
3349
                // ----- Go to the file position
3350
                @rewind($this->zip_fd);
3351
                if (@fseek($this->zip_fd, $v_header['offset'])) {
3352
                    // ----- Close the zip file
3353
                    $this->privCloseFd();
3354
3355
                    $this->privSwapBackMagicQuotes();
3356
3357
                    // ----- Error log
3358
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3359
3360
                    // ----- Return
3361
                    return PclZip::errorCode();
3362
                }
3363
3364
                // ----- Look for extraction as string
3365
                if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3366
3367
                    $v_string = '';
3368
3369
                    // ----- Extracting the file
3370
                    $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3371
                    if ($v_result1 < 1) {
3372
                        $this->privCloseFd();
3373
                        $this->privSwapBackMagicQuotes();
3374
3375
                        return $v_result1;
3376
                    }
3377
3378
                    // ----- Get the only interesting attributes
3379
                    if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) {
3380
                        // ----- Close the zip file
3381
                        $this->privCloseFd();
3382
                        $this->privSwapBackMagicQuotes();
3383
3384
                        return $v_result;
3385
                    }
3386
3387
                    // ----- Set the file content
3388
                    $p_file_list[$v_nb_extracted]['content'] = $v_string;
3389
3390
                    // ----- Next extracted file
3391
                    $v_nb_extracted++;
3392
3393
                    // ----- Look for user callback abort
3394
                    if ($v_result1 == 2) {
3395
                        break;
3396
                    }
3397
3398
                // ----- Look for extraction in standard output
3399
                } elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3400
                    // ----- Extracting the file in standard output
3401
                    $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3402
                    if ($v_result1 < 1) {
3403
                        $this->privCloseFd();
3404
                        $this->privSwapBackMagicQuotes();
3405
3406
                        return $v_result1;
3407
                    }
3408
3409
                    // ----- Get the only interesting attributes
3410
                    if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3411
                        $this->privCloseFd();
3412
                        $this->privSwapBackMagicQuotes();
3413
3414
                        return $v_result;
3415
                    }
3416
3417
                    // ----- Look for user callback abort
3418
                    if ($v_result1 == 2) {
3419
                        break;
3420
                    }
3421
3422
                // ----- Look for normal extraction
3423
                } else {
3424
                    // ----- Extracting the file
3425
                    $v_result1 = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options);
3426
                    if ($v_result1 < 1) {
3427
                        $this->privCloseFd();
3428
                        $this->privSwapBackMagicQuotes();
3429
3430
                        return $v_result1;
3431
                    }
3432
3433
                    // ----- Get the only interesting attributes
3434
                    if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3435
                        // ----- Close the zip file
3436
                        $this->privCloseFd();
3437
                        $this->privSwapBackMagicQuotes();
3438
3439
                        return $v_result;
3440
                    }
3441
3442
                    // ----- Look for user callback abort
3443
                    if ($v_result1 == 2) {
3444
                        break;
3445
                    }
3446
                }
3447
            }
3448
        }
3449
3450
        // ----- Close the zip file
3451
        $this->privCloseFd();
3452
        $this->privSwapBackMagicQuotes();
3453
3454
        // ----- Return
3455
        return $v_result;
3456
    }
3457
    // --------------------------------------------------------------------------------
3458
3459
    // --------------------------------------------------------------------------------
3460
    // Function : privExtractFile()
3461
    // Description :
3462
    // Parameters :
3463
    // Return Values :
3464
    //
3465
    // 1 : ... ?
3466
    // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3467
    // --------------------------------------------------------------------------------
3468
    public function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3469
    {
3470
        $v_result = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
3471
3472
        // ----- Read the file header
3473
        if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
3474
            // ----- Return
3475
            return $v_result;
3476
        }
3477
3478
        // ----- Check that the file header is coherent with $p_entry info
3479
        if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3480
            // TBC
3481
        }
3482
3483
        // ----- Look for all path to remove
3484
        if ($p_remove_all_path == true) {
3485
            // ----- Look for folder entry that not need to be extracted
3486
            if (($p_entry['external'] & 0x00000010) == 0x00000010) {
3487
3488
                $p_entry['status'] = "filtered";
3489
3490
                return $v_result;
3491
            }
3492
3493
            // ----- Get the basename of the path
3494
            $p_entry['filename'] = basename($p_entry['filename']);
3495
3496
        // ----- Look for path to remove
3497
        } elseif ($p_remove_path != "") {
3498
            if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) {
3499
3500
                // ----- Change the file status
3501
                $p_entry['status'] = "filtered";
3502
3503
                // ----- Return
3504
                return $v_result;
3505
            }
3506
3507
            $p_remove_path_size = strlen($p_remove_path);
3508
            if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) {
3509
3510
                // ----- Remove the path
3511
                $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3512
3513
            }
3514
        }
3515
3516
        // ----- Add the path
3517
        if ($p_path != '') {
3518
            $p_entry['filename'] = $p_path . "/" . $p_entry['filename'];
3519
        }
3520
3521
        // ----- Check a base_dir_restriction
3522
        if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3523
            $v_inclusion = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], $p_entry['filename']);
3524
            if ($v_inclusion == 0) {
3525
3526
                PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, "Filename '" . $p_entry['filename'] . "' is " . "outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3526
                PclZip::/** @scrutinizer ignore-call */ 
3527
                        privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, "Filename '" . $p_entry['filename'] . "' is " . "outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
Loading history...
3527
3528
                return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3528
                return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
3529
            }
3530
        }
3531
3532
        // ----- Look for pre-extract callback
3533
        if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3534
3535
            // ----- Generate a local information
3536
            $v_local_header = array();
3537
            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3538
3539
            // ----- Call the callback
3540
            // Here I do not use call_user_func() because I need to send a reference to the
3541
            // header.
3542
            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3543
            $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3544
            if ($v_result == 0) {
3545
                // ----- Change the file status
3546
                $p_entry['status'] = "skipped";
3547
                $v_result          = 1;
3548
            }
3549
3550
            // ----- Look for abort result
3551
            if ($v_result == 2) {
3552
                // ----- This status is internal and will be changed in 'skipped'
3553
                $p_entry['status'] = "aborted";
3554
                $v_result          = PCLZIP_ERR_USER_ABORTED;
3555
            }
3556
3557
            // ----- Update the informations
3558
            // Only some fields can be modified
3559
            $p_entry['filename'] = $v_local_header['filename'];
3560
        }
3561
3562
        // ----- Look if extraction should be done
3563
        if ($p_entry['status'] == 'ok') {
3564
3565
            // ----- Look for specific actions while the file exist
3566
            if (file_exists($p_entry['filename'])) {
3567
3568
                // ----- Look if file is a directory
3569
                if (is_dir($p_entry['filename'])) {
3570
3571
                    // ----- Change the file status
3572
                    $p_entry['status'] = "already_a_directory";
3573
3574
                    // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3575
                    // For historical reason first PclZip implementation does not stop
3576
                    // when this kind of error occurs.
3577
                    if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
3578
3579
                        PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, "Filename '" . $p_entry['filename'] . "' is " . "already used by an existing directory");
3580
3581
                        return PclZip::errorCode();
3582
                    }
3583
3584
                // ----- Look if file is write protected
3585
                } elseif (!is_writeable($p_entry['filename'])) {
3586
3587
                    // ----- Change the file status
3588
                    $p_entry['status'] = "write_protected";
3589
3590
                    // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3591
                    // For historical reason first PclZip implementation does not stop
3592
                    // when this kind of error occurs.
3593
                    if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
3594
3595
                        PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Filename '" . $p_entry['filename'] . "' exists " . "and is write protected");
3596
3597
                        return PclZip::errorCode();
3598
                    }
3599
3600
                // ----- Look if the extracted file is older
3601
                } elseif (filemtime($p_entry['filename']) > $p_entry['mtime']) {
3602
                    // ----- Change the file status
3603
                    if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) && ($p_options[PCLZIP_OPT_REPLACE_NEWER] === true)) {
3604
                    } else {
3605
                        $p_entry['status'] = "newer_exist";
3606
3607
                        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3608
                        // For historical reason first PclZip implementation does not stop
3609
                        // when this kind of error occurs.
3610
                        if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
3611
3612
                            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '" . $p_entry['filename'] . "' exists " . "and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3613
3614
                            return PclZip::errorCode();
3615
                        }
3616
                    }
3617
                } else {
3618
                }
3619
3620
            // ----- Check the directory availability and create it if necessary
3621
            } else {
3622
                if ((($p_entry['external'] & 0x00000010) == 0x00000010) || (substr($p_entry['filename'], -1) == '/')) {
3623
                    $v_dir_to_check = $p_entry['filename'];
3624
                } elseif (!strstr($p_entry['filename'], "/")) {
3625
                    $v_dir_to_check = "";
3626
                } else {
3627
                    $v_dir_to_check = dirname($p_entry['filename']);
3628
                }
3629
3630
                if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external'] & 0x00000010) == 0x00000010))) != 1) {
3631
3632
                    // ----- Change the file status
3633
                    $p_entry['status'] = "path_creation_fail";
3634
3635
                    // ----- Return
3636
                    //return $v_result;
3637
                    $v_result = 1;
3638
                }
3639
            }
3640
        }
3641
3642
        // ----- Look if extraction should be done
3643
        if ($p_entry['status'] == 'ok') {
3644
3645
            // ----- Do the extraction (if not a folder)
3646
            if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
3647
                // ----- Look for not compressed file
3648
                if ($p_entry['compression'] == 0) {
3649
3650
                    // ----- Opening destination file
3651
                    if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3652
3653
                        // ----- Change the file status
3654
                        $p_entry['status'] = "write_error";
3655
3656
                        // ----- Return
3657
                        return $v_result;
3658
                    }
3659
3660
                    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3661
                    $v_size = $p_entry['compressed_size'];
3662
                    while ($v_size != 0) {
3663
                        $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3664
                        $v_buffer    = @fread($this->zip_fd, $v_read_size);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3664
                        $v_buffer    = @fread(/** @scrutinizer ignore-type */ $this->zip_fd, $v_read_size);
Loading history...
3665
                        /* Try to speed up the code
3666
                        $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3667
                        @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3668
                        */
3669
                        @fwrite($v_dest_file, $v_buffer, $v_read_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3669
                        /** @scrutinizer ignore-unhandled */ @fwrite($v_dest_file, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3669
                        @fwrite($v_dest_file, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
Bug introduced by
It seems like $v_dest_file can also be of type false; however, parameter $stream of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3669
                        @fwrite(/** @scrutinizer ignore-type */ $v_dest_file, $v_buffer, $v_read_size);
Loading history...
3670
                        $v_size -= $v_read_size;
3671
                    }
3672
3673
                    // ----- Closing the destination file
3674
                    fclose($v_dest_file);
0 ignored issues
show
Bug introduced by
It seems like $v_dest_file can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3674
                    fclose(/** @scrutinizer ignore-type */ $v_dest_file);
Loading history...
3675
3676
                    // ----- Change the file mtime
3677
                    touch($p_entry['filename'], $p_entry['mtime']);
3678
3679
                } else {
3680
                    // ----- TBC
3681
                    // Need to be finished
3682
                    if (($p_entry['flag'] & 1) == 1) {
3683
                        PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \'' . $p_entry['filename'] . '\' is encrypted. Encrypted files are not supported.');
3684
3685
                        return PclZip::errorCode();
3686
                    }
3687
3688
                    // ----- Look for using temporary file to unzip
3689
                    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_entry['size'])))) {
3690
                        $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3691
                        if ($v_result < PCLZIP_ERR_NO_ERROR) {
3692
                            return $v_result;
3693
                        }
3694
3695
                    // ----- Look for extract in memory
3696
                    } else {
3697
3698
                        // ----- Read the compressed file in a buffer (one shot)
3699
                        $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3700
3701
                        // ----- Decompress the file
3702
                        $v_file_content = @gzinflate($v_buffer);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of gzinflate() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3702
                        $v_file_content = @gzinflate(/** @scrutinizer ignore-type */ $v_buffer);
Loading history...
3703
                        unset($v_buffer);
3704
                        if ($v_file_content === false) {
3705
3706
                            // ----- Change the file status
3707
                            // TBC
3708
                            $p_entry['status'] = "error";
3709
3710
                            return $v_result;
3711
                        }
3712
3713
                        // ----- Opening destination file
3714
                        if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3715
3716
                            // ----- Change the file status
3717
                            $p_entry['status'] = "write_error";
3718
3719
                            return $v_result;
3720
                        }
3721
3722
                        // ----- Write the uncompressed data
3723
                        @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3724
                        unset($v_file_content);
3725
3726
                        // ----- Closing the destination file
3727
                        @fclose($v_dest_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3727
                        /** @scrutinizer ignore-unhandled */ @fclose($v_dest_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3728
3729
                    }
3730
3731
                    // ----- Change the file mtime
3732
                    @touch($p_entry['filename'], $p_entry['mtime']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for touch(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3732
                    /** @scrutinizer ignore-unhandled */ @touch($p_entry['filename'], $p_entry['mtime']);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3733
                }
3734
3735
                // ----- Look for chmod option
3736
                if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3737
3738
                    // ----- Change the mode of the file
3739
                    @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3739
                    /** @scrutinizer ignore-unhandled */ @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3740
                }
3741
3742
            }
3743
        }
3744
3745
        // ----- Change abort status
3746
        if ($p_entry['status'] == "aborted") {
3747
            $p_entry['status'] = "skipped";
3748
3749
        // ----- Look for post-extract callback
3750
        } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3751
3752
            // ----- Generate a local information
3753
            $v_local_header = array();
3754
            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3755
3756
            // ----- Call the callback
3757
            // Here I do not use call_user_func() because I need to send a reference to the
3758
            // header.
3759
            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3760
            $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3761
3762
            // ----- Look for abort result
3763
            if ($v_result == 2) {
3764
                $v_result = PCLZIP_ERR_USER_ABORTED;
3765
            }
3766
        }
3767
3768
        // ----- Return
3769
        return $v_result;
3770
    }
3771
    // --------------------------------------------------------------------------------
3772
3773
    // --------------------------------------------------------------------------------
3774
    // Function : privExtractFileUsingTempFile()
3775
    // Description :
3776
    // Parameters :
3777
    // Return Values :
3778
    // --------------------------------------------------------------------------------
3779
    public function privExtractFileUsingTempFile(&$p_entry, &$p_options)
0 ignored issues
show
Unused Code introduced by
The parameter $p_options is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

3779
    public function privExtractFileUsingTempFile(&$p_entry, /** @scrutinizer ignore-unused */ &$p_options)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3780
    {
3781
        $v_result = 1;
3782
3783
        // ----- Creates a temporary file
3784
        $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz';
3785
        if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3786
            fclose($v_file);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $v_file seems to be never defined.
Loading history...
3787
            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3787
            PclZip::/** @scrutinizer ignore-call */ 
3788
                    privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode');
Loading history...
3788
3789
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3789
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
3790
        }
3791
3792
        // ----- Write gz file format header
3793
        $v_binary_data = pack('va1a1Va1a1', 0x8b1f, chr($p_entry['compression']), chr(0x00), time(), chr(0x00), chr(3));
3794
        @fwrite($v_dest_file, $v_binary_data, 10);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3794
        /** @scrutinizer ignore-unhandled */ @fwrite($v_dest_file, $v_binary_data, 10);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_dest_file can also be of type false; however, parameter $stream of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3794
        @fwrite(/** @scrutinizer ignore-type */ $v_dest_file, $v_binary_data, 10);
Loading history...
3795
3796
        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3797
        $v_size = $p_entry['compressed_size'];
3798
        while ($v_size != 0) {
3799
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3800
            $v_buffer    = @fread($this->zip_fd, $v_read_size);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3800
            $v_buffer    = @fread(/** @scrutinizer ignore-type */ $this->zip_fd, $v_read_size);
Loading history...
3801
            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
3802
            @fwrite($v_dest_file, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3802
            @fwrite($v_dest_file, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
3803
            $v_size -= $v_read_size;
3804
        }
3805
3806
        // ----- Write gz file format footer
3807
        $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
3808
        @fwrite($v_dest_file, $v_binary_data, 8);
3809
3810
        // ----- Close the temporary file
3811
        @fclose($v_dest_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3811
        /** @scrutinizer ignore-unhandled */ @fclose($v_dest_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_dest_file can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3811
        @fclose(/** @scrutinizer ignore-type */ $v_dest_file);
Loading history...
3812
3813
        // ----- Opening destination file
3814
        if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3815
            $p_entry['status'] = "write_error";
3816
3817
            return $v_result;
3818
        }
3819
3820
        // ----- Open the temporary gz file
3821
        if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
3822
            @fclose($v_dest_file);
3823
            $p_entry['status'] = "read_error";
3824
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode');
3825
3826
            return PclZip::errorCode();
3827
        }
3828
3829
        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3830
        $v_size = $p_entry['size'];
3831
        while ($v_size != 0) {
3832
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3833
            $v_buffer    = @gzread($v_src_file, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_src_file can also be of type false; however, parameter $stream of gzread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3833
            $v_buffer    = @gzread(/** @scrutinizer ignore-type */ $v_src_file, $v_read_size);
Loading history...
3834
            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
3835
            @fwrite($v_dest_file, $v_buffer, $v_read_size);
3836
            $v_size -= $v_read_size;
3837
        }
3838
        @fclose($v_dest_file);
3839
        @gzclose($v_src_file);
0 ignored issues
show
Bug introduced by
It seems like $v_src_file can also be of type false; however, parameter $stream of gzclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3839
        @gzclose(/** @scrutinizer ignore-type */ $v_src_file);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for gzclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3839
        /** @scrutinizer ignore-unhandled */ @gzclose($v_src_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3840
3841
        // ----- Delete the temporary file
3842
        @unlink($v_gzip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3842
        /** @scrutinizer ignore-unhandled */ @unlink($v_gzip_temp_name);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3843
3844
        // ----- Return
3845
        return $v_result;
3846
    }
3847
    // --------------------------------------------------------------------------------
3848
3849
    // --------------------------------------------------------------------------------
3850
    // Function : privExtractFileInOutput()
3851
    // Description :
3852
    // Parameters :
3853
    // Return Values :
3854
    // --------------------------------------------------------------------------------
3855
    public function privExtractFileInOutput(&$p_entry, &$p_options)
3856
    {
3857
        $v_result = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
3858
3859
        // ----- Read the file header
3860
        if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
3861
            return $v_result;
3862
        }
3863
3864
        // ----- Check that the file header is coherent with $p_entry info
3865
        if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3866
            // TBC
3867
        }
3868
3869
        // ----- Look for pre-extract callback
3870
        if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3871
3872
            // ----- Generate a local information
3873
            $v_local_header = array();
3874
            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3875
3876
            // ----- Call the callback
3877
            // Here I do not use call_user_func() because I need to send a reference to the
3878
            // header.
3879
            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3880
            $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3881
            if ($v_result == 0) {
3882
                // ----- Change the file status
3883
                $p_entry['status'] = "skipped";
3884
                $v_result          = 1;
3885
            }
3886
3887
            // ----- Look for abort result
3888
            if ($v_result == 2) {
3889
                // ----- This status is internal and will be changed in 'skipped'
3890
                $p_entry['status'] = "aborted";
3891
                $v_result          = PCLZIP_ERR_USER_ABORTED;
3892
            }
3893
3894
            // ----- Update the informations
3895
            // Only some fields can be modified
3896
            $p_entry['filename'] = $v_local_header['filename'];
3897
        }
3898
3899
        // ----- Trace
3900
3901
        // ----- Look if extraction should be done
3902
        if ($p_entry['status'] == 'ok') {
3903
3904
            // ----- Do the extraction (if not a folder)
3905
            if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
3906
                // ----- Look for not compressed file
3907
                if ($p_entry['compressed_size'] == $p_entry['size']) {
3908
3909
                    // ----- Read the file in a buffer (one shot)
3910
                    $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3910
                    $v_buffer = @fread(/** @scrutinizer ignore-type */ $this->zip_fd, $p_entry['compressed_size']);
Loading history...
3911
3912
                    // ----- Send the file to the output
3913
                    echo $v_buffer;
0 ignored issues
show
Bug introduced by
Are you sure $v_buffer of type false|string can be used in echo? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3913
                    echo /** @scrutinizer ignore-type */ $v_buffer;
Loading history...
3914
                    unset($v_buffer);
3915
                } else {
3916
3917
                    // ----- Read the compressed file in a buffer (one shot)
3918
                    $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3919
3920
                    // ----- Decompress the file
3921
                    $v_file_content = gzinflate($v_buffer);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of gzinflate() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3921
                    $v_file_content = gzinflate(/** @scrutinizer ignore-type */ $v_buffer);
Loading history...
3922
                    unset($v_buffer);
3923
3924
                    // ----- Send the file to the output
3925
                    echo $v_file_content;
3926
                    unset($v_file_content);
3927
                }
3928
            }
3929
        }
3930
3931
        // ----- Change abort status
3932
        if ($p_entry['status'] == "aborted") {
3933
            $p_entry['status'] = "skipped";
3934
3935
        // ----- Look for post-extract callback
3936
        } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3937
3938
            // ----- Generate a local information
3939
            $v_local_header = array();
3940
            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3941
3942
            // ----- Call the callback
3943
            // Here I do not use call_user_func() because I need to send a reference to the
3944
            // header.
3945
            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3946
            $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3947
3948
            // ----- Look for abort result
3949
            if ($v_result == 2) {
3950
                $v_result = PCLZIP_ERR_USER_ABORTED;
3951
            }
3952
        }
3953
3954
        return $v_result;
3955
    }
3956
    // --------------------------------------------------------------------------------
3957
3958
    // --------------------------------------------------------------------------------
3959
    // Function : privExtractFileAsString()
3960
    // Description :
3961
    // Parameters :
3962
    // Return Values :
3963
    // --------------------------------------------------------------------------------
3964
    public function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
3965
    {
3966
        $v_result = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
3967
3968
        // ----- Read the file header
3969
        $v_header = array();
3970
        if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
3971
            // ----- Return
3972
            return $v_result;
3973
        }
3974
3975
        // ----- Check that the file header is coherent with $p_entry info
3976
        if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3977
            // TBC
3978
        }
3979
3980
        // ----- Look for pre-extract callback
3981
        if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3982
3983
            // ----- Generate a local information
3984
            $v_local_header = array();
3985
            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3986
3987
            // ----- Call the callback
3988
            // Here I do not use call_user_func() because I need to send a reference to the
3989
            // header.
3990
            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3991
            $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3992
            if ($v_result == 0) {
3993
                // ----- Change the file status
3994
                $p_entry['status'] = "skipped";
3995
                $v_result          = 1;
3996
            }
3997
3998
            // ----- Look for abort result
3999
            if ($v_result == 2) {
4000
                // ----- This status is internal and will be changed in 'skipped'
4001
                $p_entry['status'] = "aborted";
4002
                $v_result          = PCLZIP_ERR_USER_ABORTED;
4003
            }
4004
4005
            // ----- Update the informations
4006
            // Only some fields can be modified
4007
            $p_entry['filename'] = $v_local_header['filename'];
4008
        }
4009
4010
        // ----- Look if extraction should be done
4011
        if ($p_entry['status'] == 'ok') {
4012
4013
            // ----- Do the extraction (if not a folder)
4014
            if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
4015
                // ----- Look for not compressed file
4016
                //      if ($p_entry['compressed_size'] == $p_entry['size'])
4017
                if ($p_entry['compression'] == 0) {
4018
4019
                    // ----- Reading the file
4020
                    $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4020
                    $p_string = @fread(/** @scrutinizer ignore-type */ $this->zip_fd, $p_entry['compressed_size']);
Loading history...
4021
                } else {
4022
4023
                    // ----- Reading the file
4024
                    $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4025
4026
                    // ----- Decompress the file
4027
                    if (($p_string = @gzinflate($v_data)) === false) {
0 ignored issues
show
Bug introduced by
It seems like $v_data can also be of type false; however, parameter $data of gzinflate() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4027
                    if (($p_string = @gzinflate(/** @scrutinizer ignore-type */ $v_data)) === false) {
Loading history...
4028
                        // TBC
4029
                    }
4030
                }
4031
4032
                // ----- Trace
4033
            } else {
4034
                // TBC : error : can not extract a folder in a string
4035
            }
4036
4037
        }
4038
4039
        // ----- Change abort status
4040
        if ($p_entry['status'] == "aborted") {
4041
            $p_entry['status'] = "skipped";
4042
4043
        // ----- Look for post-extract callback
4044
        } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4045
4046
            // ----- Generate a local information
4047
            $v_local_header = array();
4048
            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4049
4050
            // ----- Swap the content to header
4051
            $v_local_header['content'] = $p_string;
4052
            $p_string                  = '';
4053
4054
            // ----- Call the callback
4055
            // Here I do not use call_user_func() because I need to send a reference to the
4056
            // header.
4057
            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4058
            $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4059
4060
            // ----- Swap back the content to header
4061
            $p_string = $v_local_header['content'];
4062
            unset($v_local_header['content']);
4063
4064
            // ----- Look for abort result
4065
            if ($v_result == 2) {
4066
                $v_result = PCLZIP_ERR_USER_ABORTED;
4067
            }
4068
        }
4069
4070
        // ----- Return
4071
        return $v_result;
4072
    }
4073
    // --------------------------------------------------------------------------------
4074
4075
    // --------------------------------------------------------------------------------
4076
    // Function : privReadFileHeader()
4077
    // Description :
4078
    // Parameters :
4079
    // Return Values :
4080
    // --------------------------------------------------------------------------------
4081
    public function privReadFileHeader(&$p_header)
4082
    {
4083
        $v_result = 1;
4084
4085
        // ----- Read the 4 bytes signature
4086
        $v_binary_data = @fread($this->zip_fd, 4);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4086
        $v_binary_data = @fread(/** @scrutinizer ignore-type */ $this->zip_fd, 4);
Loading history...
4087
        $v_data        = unpack('Vid', $v_binary_data);
0 ignored issues
show
Bug introduced by
It seems like $v_binary_data can also be of type false; however, parameter $string of unpack() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4087
        $v_data        = unpack('Vid', /** @scrutinizer ignore-type */ $v_binary_data);
Loading history...
4088
4089
        // ----- Check signature
4090
        if ($v_data['id'] != 0x04034b50) {
4091
4092
            // ----- Error log
4093
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4093
            PclZip::/** @scrutinizer ignore-call */ 
4094
                    privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
Loading history...
4094
4095
            // ----- Return
4096
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4096
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
4097
        }
4098
4099
        // ----- Read the first 42 bytes of the header
4100
        $v_binary_data = fread($this->zip_fd, 26);
4101
4102
        // ----- Look for invalid block size
4103
        if (strlen($v_binary_data) != 26) {
4104
            $p_header['filename'] = "";
4105
            $p_header['status']   = "invalid_header";
4106
4107
            // ----- Error log
4108
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
4109
4110
            // ----- Return
4111
            return PclZip::errorCode();
4112
        }
4113
4114
        // ----- Extract the values
4115
        $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4116
4117
        // ----- Get filename
4118
        $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4119
4120
        // ----- Get extra_fields
4121
        if ($v_data['extra_len'] != 0) {
4122
            $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4123
        } else {
4124
            $p_header['extra'] = '';
4125
        }
4126
4127
        // ----- Extract properties
4128
        $p_header['version_extracted'] = $v_data['version'];
4129
        $p_header['compression']       = $v_data['compression'];
4130
        $p_header['size']              = $v_data['size'];
4131
        $p_header['compressed_size']   = $v_data['compressed_size'];
4132
        $p_header['crc']               = $v_data['crc'];
4133
        $p_header['flag']              = $v_data['flag'];
4134
        $p_header['filename_len']      = $v_data['filename_len'];
4135
4136
        // ----- Recuperate date in UNIX format
4137
        $p_header['mdate'] = $v_data['mdate'];
4138
        $p_header['mtime'] = $v_data['mtime'];
4139
        if ($p_header['mdate'] && $p_header['mtime']) {
4140
            // ----- Extract time
4141
            $v_hour    = ($p_header['mtime'] & 0xF800) >> 11;
4142
            $v_minute  = ($p_header['mtime'] & 0x07E0) >> 5;
4143
            $v_seconde = ($p_header['mtime'] & 0x001F) * 2;
4144
4145
            // ----- Extract date
4146
            $v_year  = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4147
            $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4148
            $v_day   = $p_header['mdate'] & 0x001F;
4149
4150
            // ----- Get UNIX date format
4151
            $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4152
4153
        } else {
4154
            $p_header['mtime'] = time();
4155
        }
4156
4157
        // TBC
4158
        //for (reset($v_data); $key = key($v_data); next($v_data)) {
4159
        //}
4160
4161
        // ----- Set the stored filename
4162
        $p_header['stored_filename'] = $p_header['filename'];
4163
4164
        // ----- Set the status field
4165
        $p_header['status'] = "ok";
4166
4167
        // ----- Return
4168
        return $v_result;
4169
    }
4170
    // --------------------------------------------------------------------------------
4171
4172
    // --------------------------------------------------------------------------------
4173
    // Function : privReadCentralFileHeader()
4174
    // Description :
4175
    // Parameters :
4176
    // Return Values :
4177
    // --------------------------------------------------------------------------------
4178
    public function privReadCentralFileHeader(&$p_header)
4179
    {
4180
        $v_result = 1;
4181
4182
        // ----- Read the 4 bytes signature
4183
        $v_binary_data = @fread($this->zip_fd, 4);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4183
        $v_binary_data = @fread(/** @scrutinizer ignore-type */ $this->zip_fd, 4);
Loading history...
4184
        $v_data        = unpack('Vid', $v_binary_data);
0 ignored issues
show
Bug introduced by
It seems like $v_binary_data can also be of type false; however, parameter $string of unpack() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4184
        $v_data        = unpack('Vid', /** @scrutinizer ignore-type */ $v_binary_data);
Loading history...
4185
4186
        // ----- Check signature
4187
        if ($v_data['id'] != 0x02014b50) {
4188
4189
            // ----- Error log
4190
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4190
            PclZip::/** @scrutinizer ignore-call */ 
4191
                    privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
Loading history...
4191
4192
            // ----- Return
4193
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4193
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
4194
        }
4195
4196
        // ----- Read the first 42 bytes of the header
4197
        $v_binary_data = fread($this->zip_fd, 42);
4198
4199
        // ----- Look for invalid block size
4200
        if (strlen($v_binary_data) != 42) {
4201
            $p_header['filename'] = "";
4202
            $p_header['status']   = "invalid_header";
4203
4204
            // ----- Error log
4205
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
4206
4207
            // ----- Return
4208
            return PclZip::errorCode();
4209
        }
4210
4211
        // ----- Extract the values
4212
        $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
4213
4214
        // ----- Get filename
4215
        if ($p_header['filename_len'] != 0) {
4216
            $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4217
        } else {
4218
            $p_header['filename'] = '';
4219
        }
4220
4221
        // ----- Get extra
4222
        if ($p_header['extra_len'] != 0) {
4223
            $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4224
        } else {
4225
            $p_header['extra'] = '';
4226
        }
4227
4228
        // ----- Get comment
4229
        if ($p_header['comment_len'] != 0) {
4230
            $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4231
        } else {
4232
            $p_header['comment'] = '';
4233
        }
4234
4235
        // ----- Extract properties
4236
4237
        // ----- Recuperate date in UNIX format
4238
        //if ($p_header['mdate'] && $p_header['mtime'])
4239
        // TBC : bug : this was ignoring time with 0/0/0
4240
        if (1) {
4241
            // ----- Extract time
4242
            $v_hour    = ($p_header['mtime'] & 0xF800) >> 11;
4243
            $v_minute  = ($p_header['mtime'] & 0x07E0) >> 5;
4244
            $v_seconde = ($p_header['mtime'] & 0x001F) * 2;
4245
4246
            // ----- Extract date
4247
            $v_year  = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4248
            $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4249
            $v_day   = $p_header['mdate'] & 0x001F;
4250
4251
            // ----- Get UNIX date format
4252
            $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4253
4254
        } else {
4255
            $p_header['mtime'] = time();
4256
        }
4257
4258
        // ----- Set the stored filename
4259
        $p_header['stored_filename'] = $p_header['filename'];
4260
4261
        // ----- Set default status to ok
4262
        $p_header['status'] = 'ok';
4263
4264
        // ----- Look if it is a directory
4265
        if (substr($p_header['filename'], -1) == '/') {
4266
            //$p_header['external'] = 0x41FF0010;
4267
            $p_header['external'] = 0x00000010;
4268
        }
4269
4270
        // ----- Return
4271
        return $v_result;
4272
    }
4273
    // --------------------------------------------------------------------------------
4274
4275
    // --------------------------------------------------------------------------------
4276
    // Function : privCheckFileHeaders()
4277
    // Description :
4278
    // Parameters :
4279
    // Return Values :
4280
    //   1 on success,
4281
    //   0 on error;
4282
    // --------------------------------------------------------------------------------
4283
    public function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4284
    {
4285
        $v_result = 1;
4286
4287
        // ----- Check the static values
4288
        // TBC
4289
        if ($p_local_header['filename'] != $p_central_header['filename']) {
4290
        }
4291
        if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4292
        }
4293
        if ($p_local_header['flag'] != $p_central_header['flag']) {
4294
        }
4295
        if ($p_local_header['compression'] != $p_central_header['compression']) {
4296
        }
4297
        if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4298
        }
4299
        if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4300
        }
4301
4302
        // ----- Look for flag bit 3
4303
        if (($p_local_header['flag'] & 8) == 8) {
4304
            $p_local_header['size']            = $p_central_header['size'];
4305
            $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4306
            $p_local_header['crc']             = $p_central_header['crc'];
4307
        }
4308
4309
        // ----- Return
4310
        return $v_result;
4311
    }
4312
    // --------------------------------------------------------------------------------
4313
4314
    // --------------------------------------------------------------------------------
4315
    // Function : privReadEndCentralDir()
4316
    // Description :
4317
    // Parameters :
4318
    // Return Values :
4319
    // --------------------------------------------------------------------------------
4320
    public function privReadEndCentralDir(&$p_central_dir)
4321
    {
4322
        $v_result = 1;
4323
4324
        // ----- Go to the end of the zip file
4325
        $v_size = filesize($this->zipname);
4326
        @fseek($this->zip_fd, $v_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fseek(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4326
        /** @scrutinizer ignore-unhandled */ @fseek($this->zip_fd, $v_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fseek(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4326
        @fseek(/** @scrutinizer ignore-type */ $this->zip_fd, $v_size);
Loading history...
4327
        if (@ftell($this->zip_fd) != $v_size) {
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of ftell(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4327
        if (@ftell(/** @scrutinizer ignore-type */ $this->zip_fd) != $v_size) {
Loading history...
4328
            // ----- Error log
4329
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \'' . $this->zipname . '\'');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4329
            PclZip::/** @scrutinizer ignore-call */ 
4330
                    privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \'' . $this->zipname . '\'');
Loading history...
4330
4331
            // ----- Return
4332
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4332
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
4333
        }
4334
4335
        // ----- First try : look if this is an archive with no commentaries (most of the time)
4336
        // in this case the end of central dir is at 22 bytes of the file end
4337
        $v_found = 0;
4338
        if ($v_size > 26) {
4339
            @fseek($this->zip_fd, $v_size - 22);
4340
            if (($v_pos = @ftell($this->zip_fd)) != ($v_size - 22)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $v_pos is dead and can be removed.
Loading history...
4341
                // ----- Error log
4342
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\'');
4343
4344
                // ----- Return
4345
                return PclZip::errorCode();
4346
            }
4347
4348
            // ----- Read for bytes
4349
            $v_binary_data = @fread($this->zip_fd, 4);
0 ignored issues
show
Bug introduced by
$this->zip_fd of type integer is incompatible with the type resource expected by parameter $stream of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4349
            $v_binary_data = @fread(/** @scrutinizer ignore-type */ $this->zip_fd, 4);
Loading history...
4350
            $v_data        = @unpack('Vid', $v_binary_data);
0 ignored issues
show
Bug introduced by
It seems like $v_binary_data can also be of type false; however, parameter $string of unpack() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4350
            $v_data        = @unpack('Vid', /** @scrutinizer ignore-type */ $v_binary_data);
Loading history...
4351
4352
            // ----- Check signature
4353
            if ($v_data['id'] == 0x06054b50) {
4354
                $v_found = 1;
4355
            }
4356
4357
            $v_pos = ftell($this->zip_fd);
4358
        }
4359
4360
        // ----- Go back to the maximum possible size of the Central Dir End Record
4361
        if (!$v_found) {
4362
            $v_maximum_size = 65557; // 0xFFFF + 22;
4363
            if ($v_maximum_size > $v_size) {
4364
                $v_maximum_size = $v_size;
4365
            }
4366
            @fseek($this->zip_fd, $v_size - $v_maximum_size);
4367
            if (@ftell($this->zip_fd) != ($v_size - $v_maximum_size)) {
4368
                // ----- Error log
4369
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\'');
4370
4371
                // ----- Return
4372
                return PclZip::errorCode();
4373
            }
4374
4375
            // ----- Read byte per byte in order to find the signature
4376
            $v_pos   = ftell($this->zip_fd);
4377
            $v_bytes = 0x00000000;
4378
            while ($v_pos < $v_size) {
4379
                // ----- Read a byte
4380
                $v_byte = @fread($this->zip_fd, 1);
4381
4382
                // -----  Add the byte
4383
                //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
4384
                // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
4385
                // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
4386
                $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | ord($v_byte);
0 ignored issues
show
Bug introduced by
It seems like $v_byte can also be of type false; however, parameter $character of ord() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4386
                $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | ord(/** @scrutinizer ignore-type */ $v_byte);
Loading history...
4387
4388
                // ----- Compare the bytes
4389
                if ($v_bytes == 0x504b0506) {
4390
                    $v_pos++;
4391
                    break;
4392
                }
4393
4394
                $v_pos++;
4395
            }
4396
4397
            // ----- Look if not found end of central dir
4398
            if ($v_pos == $v_size) {
4399
4400
                // ----- Error log
4401
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4402
4403
                // ----- Return
4404
                return PclZip::errorCode();
4405
            }
4406
        }
4407
4408
        // ----- Read the first 18 bytes of the header
4409
        $v_binary_data = fread($this->zip_fd, 18);
4410
4411
        // ----- Look for invalid block size
4412
        if (strlen($v_binary_data) != 18) {
4413
4414
            // ----- Error log
4415
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : " . strlen($v_binary_data));
4416
4417
            // ----- Return
4418
            return PclZip::errorCode();
4419
        }
4420
4421
        // ----- Extract the values
4422
        $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4423
4424
        // ----- Check the global size
4425
        if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $v_pos does not seem to be defined for all execution paths leading up to this point.
Loading history...
4426
4427
            // ----- Removed in release 2.2 see readme file
4428
            // The check of the file size is a little too strict.
4429
            // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4430
            // While decrypted, zip has training 0 bytes
4431
            if (0) {
4432
                // ----- Error log
4433
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'The central dir is not at the end of the archive.' . ' Some trailing bytes exists after the archive.');
4434
4435
                // ----- Return
4436
                return PclZip::errorCode();
4437
            }
4438
        }
4439
4440
        // ----- Get comment
4441
        if ($v_data['comment_size'] != 0) {
4442
            $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4443
        } else {
4444
            $p_central_dir['comment'] = '';
4445
        }
4446
4447
        $p_central_dir['entries']      = $v_data['entries'];
4448
        $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4449
        $p_central_dir['offset']       = $v_data['offset'];
4450
        $p_central_dir['size']         = $v_data['size'];
4451
        $p_central_dir['disk']         = $v_data['disk'];
4452
        $p_central_dir['disk_start']   = $v_data['disk_start'];
4453
4454
        // TBC
4455
        //for (reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4456
        //}
4457
4458
        // ----- Return
4459
        return $v_result;
4460
    }
4461
    // --------------------------------------------------------------------------------
4462
4463
    // --------------------------------------------------------------------------------
4464
    // Function : privDeleteByRule()
4465
    // Description :
4466
    // Parameters :
4467
    // Return Values :
4468
    // --------------------------------------------------------------------------------
4469
    public function privDeleteByRule(&$p_result_list, &$p_options)
4470
    {
4471
        $v_result      = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $v_result is dead and can be removed.
Loading history...
4472
        $v_list_detail = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $v_list_detail is dead and can be removed.
Loading history...
4473
4474
        // ----- Open the zip file
4475
        if (($v_result = $this->privOpenFd('rb')) != 1) {
4476
            // ----- Return
4477
            return $v_result;
4478
        }
4479
4480
        // ----- Read the central directory informations
4481
        $v_central_dir = array();
4482
        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
4483
            $this->privCloseFd();
4484
4485
            return $v_result;
4486
        }
4487
4488
        // ----- Go to beginning of File
4489
        @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rewind(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4489
        /** @scrutinizer ignore-unhandled */ @rewind($this->zip_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4489
        @rewind(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
4490
4491
        // ----- Scan all the files
4492
        // ----- Start at beginning of Central Dir
4493
        $v_pos_entry = $v_central_dir['offset'];
4494
        @rewind($this->zip_fd);
4495
        if (@fseek($this->zip_fd, $v_pos_entry)) {
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of fseek() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4495
        if (@fseek(/** @scrutinizer ignore-type */ $this->zip_fd, $v_pos_entry)) {
Loading history...
4496
            // ----- Close the zip file
4497
            $this->privCloseFd();
4498
4499
            // ----- Error log
4500
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4500
            PclZip::/** @scrutinizer ignore-call */ 
4501
                    privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
Loading history...
4501
4502
            // ----- Return
4503
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4503
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
4504
        }
4505
4506
        // ----- Read each entry
4507
        $v_header_list = array();
4508
        $j_start       = 0;
4509
        for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {
4510
4511
            // ----- Read the file header
4512
            $v_header_list[$v_nb_extracted] = array();
4513
            if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) {
4514
                // ----- Close the zip file
4515
                $this->privCloseFd();
4516
4517
                return $v_result;
4518
            }
4519
4520
            // ----- Store the index
4521
            $v_header_list[$v_nb_extracted]['index'] = $i;
4522
4523
            // ----- Look for the specific extract rules
4524
            $v_found = false;
4525
4526
            // ----- Look for extract by name rule
4527
            if ((isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4528
4529
                // ----- Look if the filename is in the list
4530
                for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4531
4532
                    // ----- Look for a directory
4533
                    if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4534
4535
                        // ----- Look if the directory is in the filename path
4536
                        if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4537
                            $v_found = true;
4538
                        } elseif ((($v_header_list[$v_nb_extracted]['external'] & 0x00000010) == 0x00000010) /* Indicates a folder */ && ($v_header_list[$v_nb_extracted]['stored_filename'] . '/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4539
                            $v_found = true;
4540
                        }
4541
4542
                    // ----- Look for a filename
4543
                    } elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4544
                        $v_found = true;
4545
                    }
4546
                }
4547
4548
            // ----- Look for extract by ereg rule
4549
            // ereg() is deprecated with PHP 5.3
4550
            /*
4551
            elseif (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
4552
            && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4553
4554
            if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4555
            $v_found = true;
4556
            }
4557
            }
4558
            */
4559
4560
            // ----- Look for extract by preg rule
4561
            } elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4562
4563
                if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4564
                    $v_found = true;
4565
                }
4566
4567
            // ----- Look for extract by index rule
4568
            } elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4569
4570
                // ----- Look if the index is in the list
4571
                for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4572
4573
                    if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4574
                        $v_found = true;
4575
                    }
4576
                    if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4577
                        $j_start = $j + 1;
4578
                    }
4579
4580
                    if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) {
4581
                        break;
4582
                    }
4583
                }
4584
            } else {
4585
                $v_found = true;
4586
            }
4587
4588
            // ----- Look for deletion
4589
            if ($v_found) {
4590
                unset($v_header_list[$v_nb_extracted]);
4591
            } else {
4592
                $v_nb_extracted++;
4593
            }
4594
        }
4595
4596
        // ----- Look if something need to be deleted
4597
        if ($v_nb_extracted > 0) {
4598
4599
            // ----- Creates a temporay file
4600
            $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
4601
4602
            // ----- Creates a temporary zip archive
4603
            $v_temp_zip = new PclZip($v_zip_temp_name);
4604
4605
            // ----- Open the temporary zip file in write mode
4606
            if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4607
                $this->privCloseFd();
4608
4609
                // ----- Return
4610
                return $v_result;
4611
            }
4612
4613
            // ----- Look which file need to be kept
4614
            for ($i = 0; $i < sizeof($v_header_list); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
4615
4616
                // ----- Calculate the position of the header
4617
                @rewind($this->zip_fd);
4618
                if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
4619
                    // ----- Close the zip file
4620
                    $this->privCloseFd();
4621
                    $v_temp_zip->privCloseFd();
4622
                    @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4622
                    /** @scrutinizer ignore-unhandled */ @unlink($v_zip_temp_name);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
4623
4624
                    // ----- Error log
4625
                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4626
4627
                    // ----- Return
4628
                    return PclZip::errorCode();
4629
                }
4630
4631
                // ----- Read the file header
4632
                $v_local_header = array();
4633
                if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4634
                    // ----- Close the zip file
4635
                    $this->privCloseFd();
4636
                    $v_temp_zip->privCloseFd();
4637
                    @unlink($v_zip_temp_name);
4638
4639
                    // ----- Return
4640
                    return $v_result;
4641
                }
4642
4643
                // ----- Check that local file header is same as central file header
4644
                if ($this->privCheckFileHeaders($v_local_header, $v_header_list[$i]) != 1) {
4645
                    // TBC
4646
                }
4647
                unset($v_local_header);
4648
4649
                // ----- Write the file header
4650
                if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4651
                    // ----- Close the zip file
4652
                    $this->privCloseFd();
4653
                    $v_temp_zip->privCloseFd();
4654
                    @unlink($v_zip_temp_name);
4655
4656
                    // ----- Return
4657
                    return $v_result;
4658
                }
4659
4660
                // ----- Read/write the data block
4661
                if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4662
                    // ----- Close the zip file
4663
                    $this->privCloseFd();
4664
                    $v_temp_zip->privCloseFd();
4665
                    @unlink($v_zip_temp_name);
4666
4667
                    // ----- Return
4668
                    return $v_result;
4669
                }
4670
            }
4671
4672
            // ----- Store the offset of the central dir
4673
            $v_offset = @ftell($v_temp_zip->zip_fd);
0 ignored issues
show
Bug introduced by
It seems like $v_temp_zip->zip_fd can also be of type false and integer; however, parameter $stream of ftell() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4673
            $v_offset = @ftell(/** @scrutinizer ignore-type */ $v_temp_zip->zip_fd);
Loading history...
4674
4675
            // ----- Re-Create the Central Dir files header
4676
            for ($i = 0; $i < sizeof($v_header_list); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
4677
                // ----- Create the file header
4678
                if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4679
                    $v_temp_zip->privCloseFd();
4680
                    $this->privCloseFd();
4681
                    @unlink($v_zip_temp_name);
4682
4683
                    // ----- Return
4684
                    return $v_result;
4685
                }
4686
4687
                // ----- Transform the header to a 'usable' info
4688
                $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4689
            }
4690
4691
            // ----- Zip file comment
4692
            $v_comment = '';
4693
            if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4694
                $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4695
            }
4696
4697
            // ----- Calculate the size of the central header
4698
            $v_size = @ftell($v_temp_zip->zip_fd) - $v_offset;
4699
4700
            // ----- Create the central dir footer
4701
            if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4702
                // ----- Reset the file list
4703
                unset($v_header_list);
4704
                $v_temp_zip->privCloseFd();
4705
                $this->privCloseFd();
4706
                @unlink($v_zip_temp_name);
4707
4708
                // ----- Return
4709
                return $v_result;
4710
            }
4711
4712
            // ----- Close
4713
            $v_temp_zip->privCloseFd();
4714
            $this->privCloseFd();
4715
4716
            // ----- Delete the zip file
4717
            // TBC : I should test the result ...
4718
            @unlink($this->zipname);
4719
4720
            // ----- Rename the temporary file
4721
            // TBC : I should test the result ...
4722
            //@rename($v_zip_temp_name, $this->zipname);
4723
            PclZipUtilRename($v_zip_temp_name, $this->zipname);
4724
4725
            // ----- Destroy the temporary archive
4726
            unset($v_temp_zip);
4727
4728
        // ----- Remove every files : reset the file
4729
        } elseif ($v_central_dir['entries'] != 0) {
4730
            $this->privCloseFd();
4731
4732
            if (($v_result = $this->privOpenFd('wb')) != 1) {
4733
                return $v_result;
4734
            }
4735
4736
            if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4737
                return $v_result;
4738
            }
4739
4740
            $this->privCloseFd();
4741
        }
4742
4743
        // ----- Return
4744
        return $v_result;
4745
    }
4746
    // --------------------------------------------------------------------------------
4747
4748
    // --------------------------------------------------------------------------------
4749
    // Function : privDirCheck()
4750
    // Description :
4751
    //   Check if a directory exists, if not it creates it and all the parents directory
4752
    //   which may be useful.
4753
    // Parameters :
4754
    //   $p_dir : Directory path to check.
4755
    // Return Values :
4756
    //    1 : OK
4757
    //   -1 : Unable to create directory
4758
    // --------------------------------------------------------------------------------
4759
    public function privDirCheck($p_dir, $p_is_dir = false)
4760
    {
4761
        $v_result = 1;
4762
4763
        // ----- Remove the final '/'
4764
        if (($p_is_dir) && (substr($p_dir, -1) == '/')) {
4765
            $p_dir = substr($p_dir, 0, strlen($p_dir) - 1);
4766
        }
4767
4768
        // ----- Check the directory availability
4769
        if ((is_dir($p_dir)) || ($p_dir == "")) {
4770
            return 1;
4771
        }
4772
4773
        // ----- Extract parent directory
4774
        $p_parent_dir = dirname($p_dir);
4775
4776
        // ----- Just a check
4777
        if ($p_parent_dir != $p_dir) {
4778
            // ----- Look for parent directory
4779
            if ($p_parent_dir != "") {
4780
                if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) {
4781
                    return $v_result;
4782
                }
4783
            }
4784
        }
4785
4786
        // ----- Create the directory
4787
        if (!@mkdir($p_dir, 0777)) {
4788
            // ----- Error log
4789
            PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4789
            PclZip::/** @scrutinizer ignore-call */ 
4790
                    privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
Loading history...
4790
4791
            // ----- Return
4792
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4792
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
4793
        }
4794
4795
        // ----- Return
4796
        return $v_result;
4797
    }
4798
    // --------------------------------------------------------------------------------
4799
4800
    // --------------------------------------------------------------------------------
4801
    // Function : privMerge()
4802
    // Description :
4803
    //   If $p_archive_to_add does not exist, the function exit with a success result.
4804
    // Parameters :
4805
    // Return Values :
4806
    // --------------------------------------------------------------------------------
4807
    public function privMerge(&$p_archive_to_add)
4808
    {
4809
        $v_result = 1;
4810
4811
        // ----- Look if the archive_to_add exists
4812
        if (!is_file($p_archive_to_add->zipname)) {
4813
4814
            // ----- Nothing to merge, so merge is a success
4815
            $v_result = 1;
4816
4817
            // ----- Return
4818
            return $v_result;
4819
        }
4820
4821
        // ----- Look if the archive exists
4822
        if (!is_file($this->zipname)) {
4823
4824
            // ----- Do a duplicate
4825
            $v_result = $this->privDuplicate($p_archive_to_add->zipname);
4826
4827
            // ----- Return
4828
            return $v_result;
4829
        }
4830
4831
        // ----- Open the zip file
4832
        if (($v_result = $this->privOpenFd('rb')) != 1) {
4833
            // ----- Return
4834
            return $v_result;
4835
        }
4836
4837
        // ----- Read the central directory informations
4838
        $v_central_dir = array();
4839
        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
4840
            $this->privCloseFd();
4841
4842
            return $v_result;
4843
        }
4844
4845
        // ----- Go to beginning of File
4846
        @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rewind(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4846
        /** @scrutinizer ignore-unhandled */ @rewind($this->zip_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4846
        @rewind(/** @scrutinizer ignore-type */ $this->zip_fd);
Loading history...
4847
4848
        // ----- Open the archive_to_add file
4849
        if (($v_result = $p_archive_to_add->privOpenFd('rb')) != 1) {
4850
            $this->privCloseFd();
4851
4852
            // ----- Return
4853
            return $v_result;
4854
        }
4855
4856
        // ----- Read the central directory informations
4857
        $v_central_dir_to_add = array();
4858
        if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) {
4859
            $this->privCloseFd();
4860
            $p_archive_to_add->privCloseFd();
4861
4862
            return $v_result;
4863
        }
4864
4865
        // ----- Go to beginning of File
4866
        @rewind($p_archive_to_add->zip_fd);
4867
4868
        // ----- Creates a temporay file
4869
        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
4870
4871
        // ----- Open the temporary file in write mode
4872
        if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
4873
            $this->privCloseFd();
4874
            $p_archive_to_add->privCloseFd();
4875
4876
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4876
            PclZip::/** @scrutinizer ignore-call */ 
4877
                    privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode');
Loading history...
4877
4878
            // ----- Return
4879
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4879
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
4880
        }
4881
4882
        // ----- Copy the files from the archive to the temporary file
4883
        // TBC : Here I should better append the file and go back to erase the central dir
4884
        $v_size = $v_central_dir['offset'];
4885
        while ($v_size != 0) {
4886
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4887
            $v_buffer    = fread($this->zip_fd, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4887
            $v_buffer    = fread(/** @scrutinizer ignore-type */ $this->zip_fd, $v_read_size);
Loading history...
4888
            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false; however, parameter $stream of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4888
            @fwrite(/** @scrutinizer ignore-type */ $v_zip_temp_fd, $v_buffer, $v_read_size);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4888
            /** @scrutinizer ignore-unhandled */ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
4889
            $v_size -= $v_read_size;
4890
        }
4891
4892
        // ----- Copy the files from the archive_to_add into the temporary file
4893
        $v_size = $v_central_dir_to_add['offset'];
4894
        while ($v_size != 0) {
4895
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4896
            $v_buffer    = fread($p_archive_to_add->zip_fd, $v_read_size);
4897
            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
4898
            $v_size -= $v_read_size;
4899
        }
4900
4901
        // ----- Store the offset of the central dir
4902
        $v_offset = @ftell($v_zip_temp_fd);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false; however, parameter $stream of ftell() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4902
        $v_offset = @ftell(/** @scrutinizer ignore-type */ $v_zip_temp_fd);
Loading history...
4903
4904
        // ----- Copy the block of file headers from the old archive
4905
        $v_size = $v_central_dir['size'];
4906
        while ($v_size != 0) {
4907
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4908
            $v_buffer    = @fread($this->zip_fd, $v_read_size);
4909
            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4909
            @fwrite($v_zip_temp_fd, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
4910
            $v_size -= $v_read_size;
4911
        }
4912
4913
        // ----- Copy the block of file headers from the archive_to_add
4914
        $v_size = $v_central_dir_to_add['size'];
4915
        while ($v_size != 0) {
4916
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4917
            $v_buffer    = @fread($p_archive_to_add->zip_fd, $v_read_size);
4918
            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
4919
            $v_size -= $v_read_size;
4920
        }
4921
4922
        // ----- Merge the file comments
4923
        $v_comment = $v_central_dir['comment'] . ' ' . $v_central_dir_to_add['comment'];
4924
4925
        // ----- Calculate the size of the (new) central header
4926
        $v_size = @ftell($v_zip_temp_fd) - $v_offset;
4927
4928
        // ----- Swap the file descriptor
4929
        // Here is a trick : I swap the temporary fd with the zip fd, in order to use
4930
        // the following methods on the temporary fil and not the real archive fd
4931
        $v_swap        = $this->zip_fd;
4932
        $this->zip_fd  = $v_zip_temp_fd;
4933
        $v_zip_temp_fd = $v_swap;
4934
4935
        // ----- Create the central dir footer
4936
        if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries'] + $v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) {
4937
            $this->privCloseFd();
4938
            $p_archive_to_add->privCloseFd();
4939
            @fclose($v_zip_temp_fd);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false and integer; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4939
            @fclose(/** @scrutinizer ignore-type */ $v_zip_temp_fd);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4939
            /** @scrutinizer ignore-unhandled */ @fclose($v_zip_temp_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
4940
            $this->zip_fd = null;
4941
4942
            // ----- Reset the file list
4943
            unset($v_header_list);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $v_header_list seems to be never defined.
Loading history...
4944
4945
            // ----- Return
4946
            return $v_result;
4947
        }
4948
4949
        // ----- Swap back the file descriptor
4950
        $v_swap        = $this->zip_fd;
4951
        $this->zip_fd  = $v_zip_temp_fd;
4952
        $v_zip_temp_fd = $v_swap;
4953
4954
        // ----- Close
4955
        $this->privCloseFd();
4956
        $p_archive_to_add->privCloseFd();
4957
4958
        // ----- Close the temporary file
4959
        @fclose($v_zip_temp_fd);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4959
        @fclose(/** @scrutinizer ignore-type */ $v_zip_temp_fd);
Loading history...
4960
4961
        // ----- Delete the zip file
4962
        // TBC : I should test the result ...
4963
        @unlink($this->zipname);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4963
        /** @scrutinizer ignore-unhandled */ @unlink($this->zipname);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
4964
4965
        // ----- Rename the temporary file
4966
        // TBC : I should test the result ...
4967
        //@rename($v_zip_temp_name, $this->zipname);
4968
        PclZipUtilRename($v_zip_temp_name, $this->zipname);
4969
4970
        // ----- Return
4971
        return $v_result;
4972
    }
4973
    // --------------------------------------------------------------------------------
4974
4975
    // --------------------------------------------------------------------------------
4976
    // Function : privDuplicate()
4977
    // Description :
4978
    // Parameters :
4979
    // Return Values :
4980
    // --------------------------------------------------------------------------------
4981
    public function privDuplicate($p_archive_filename)
4982
    {
4983
        $v_result = 1;
4984
4985
        // ----- Look if the $p_archive_filename exists
4986
        if (!is_file($p_archive_filename)) {
4987
4988
            // ----- Nothing to duplicate, so duplicate is a success.
4989
            $v_result = 1;
4990
4991
            // ----- Return
4992
            return $v_result;
4993
        }
4994
4995
        // ----- Open the zip file
4996
        if (($v_result = $this->privOpenFd('wb')) != 1) {
4997
            // ----- Return
4998
            return $v_result;
4999
        }
5000
5001
        // ----- Open the temporary file in write mode
5002
        if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) {
5003
            $this->privCloseFd();
5004
5005
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \'' . $p_archive_filename . '\' in binary write mode');
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::privErrorLog() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

5005
            PclZip::/** @scrutinizer ignore-call */ 
5006
                    privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \'' . $p_archive_filename . '\' in binary write mode');
Loading history...
5006
5007
            // ----- Return
5008
            return PclZip::errorCode();
0 ignored issues
show
Bug Best Practice introduced by
The method PclZip::errorCode() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

5008
            return PclZip::/** @scrutinizer ignore-call */ errorCode();
Loading history...
5009
        }
5010
5011
        // ----- Copy the files from the archive to the temporary file
5012
        // TBC : Here I should better append the file and go back to erase the central dir
5013
        $v_size = filesize($p_archive_filename);
5014
        while ($v_size != 0) {
5015
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5016
            $v_buffer    = fread($v_zip_temp_fd, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false; however, parameter $stream of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5016
            $v_buffer    = fread(/** @scrutinizer ignore-type */ $v_zip_temp_fd, $v_read_size);
Loading history...
5017
            @fwrite($this->zip_fd, $v_buffer, $v_read_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

5017
            /** @scrutinizer ignore-unhandled */ @fwrite($this->zip_fd, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $this->zip_fd can also be of type false and integer; however, parameter $stream of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5017
            @fwrite(/** @scrutinizer ignore-type */ $this->zip_fd, $v_buffer, $v_read_size);
Loading history...
5018
            $v_size -= $v_read_size;
5019
        }
5020
5021
        // ----- Close
5022
        $this->privCloseFd();
5023
5024
        // ----- Close the temporary file
5025
        @fclose($v_zip_temp_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

5025
        /** @scrutinizer ignore-unhandled */ @fclose($v_zip_temp_fd);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $v_zip_temp_fd can also be of type false; however, parameter $stream of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5025
        @fclose(/** @scrutinizer ignore-type */ $v_zip_temp_fd);
Loading history...
5026
5027
        // ----- Return
5028
        return $v_result;
5029
    }
5030
    // --------------------------------------------------------------------------------
5031
5032
    // --------------------------------------------------------------------------------
5033
    // Function : privErrorLog()
5034
    // Description :
5035
    // Parameters :
5036
    // --------------------------------------------------------------------------------
5037
    public function privErrorLog($p_error_code = 0, $p_error_string = '')
5038
    {
5039
        if (PCLZIP_ERROR_EXTERNAL == 1) {
0 ignored issues
show
introduced by
The condition PCLZIP_ERROR_EXTERNAL == 1 is always false.
Loading history...
5040
            PclError($p_error_code, $p_error_string);
0 ignored issues
show
Bug introduced by
The function PclError was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

5040
            /** @scrutinizer ignore-call */ 
5041
            PclError($p_error_code, $p_error_string);
Loading history...
5041
        } else {
5042
            $this->error_code   = $p_error_code;
5043
            $this->error_string = $p_error_string;
5044
        }
5045
    }
5046
    // --------------------------------------------------------------------------------
5047
5048
    // --------------------------------------------------------------------------------
5049
    // Function : privErrorReset()
5050
    // Description :
5051
    // Parameters :
5052
    // --------------------------------------------------------------------------------
5053
    public function privErrorReset()
5054
    {
5055
        if (PCLZIP_ERROR_EXTERNAL == 1) {
0 ignored issues
show
introduced by
The condition PCLZIP_ERROR_EXTERNAL == 1 is always false.
Loading history...
5056
            PclErrorReset();
0 ignored issues
show
Bug introduced by
The function PclErrorReset was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

5056
            /** @scrutinizer ignore-call */ 
5057
            PclErrorReset();
Loading history...
5057
        } else {
5058
            $this->error_code   = 0;
5059
            $this->error_string = '';
5060
        }
5061
    }
5062
    // --------------------------------------------------------------------------------
5063
5064
    // --------------------------------------------------------------------------------
5065
    // Function : privDisableMagicQuotes()
5066
    // Description :
5067
    // Parameters :
5068
    // Return Values :
5069
    // --------------------------------------------------------------------------------
5070
    public function privDisableMagicQuotes()
5071
    {
5072
        $v_result = 1;
5073
5074
        // ----- Look if function exists
5075
        if ((!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) {
5076
            return $v_result;
5077
        }
5078
5079
        // ----- Look if already done
5080
        if ($this->magic_quotes_status != -1) {
5081
            return $v_result;
5082
        }
5083
5084
        // ----- Get and memorize the magic_quote value
5085
        $this->magic_quotes_status = @get_magic_quotes_runtime();
5086
5087
        // ----- Disable magic_quotes
5088
        if ($this->magic_quotes_status == 1) {
5089
            @set_magic_quotes_runtime(0);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for set_magic_quotes_runtime(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

5089
            /** @scrutinizer ignore-unhandled */ @set_magic_quotes_runtime(0);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
5090
        }
5091
5092
        // ----- Return
5093
        return $v_result;
5094
    }
5095
    // --------------------------------------------------------------------------------
5096
5097
    // --------------------------------------------------------------------------------
5098
    // Function : privSwapBackMagicQuotes()
5099
    // Description :
5100
    // Parameters :
5101
    // Return Values :
5102
    // --------------------------------------------------------------------------------
5103
    public function privSwapBackMagicQuotes()
5104
    {
5105
        $v_result = 1;
5106
5107
        // ----- Look if function exists
5108
        if ((!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) {
5109
            return $v_result;
5110
        }
5111
5112
        // ----- Look if something to do
5113
        if ($this->magic_quotes_status != -1) {
5114
            return $v_result;
5115
        }
5116
5117
        // ----- Swap back magic_quotes
5118
        if ($this->magic_quotes_status == 1) {
5119
            @set_magic_quotes_runtime($this->magic_quotes_status);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for set_magic_quotes_runtime(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

5119
            /** @scrutinizer ignore-unhandled */ @set_magic_quotes_runtime($this->magic_quotes_status);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
5120
        }
5121
5122
        // ----- Return
5123
        return $v_result;
5124
    }
5125
    // --------------------------------------------------------------------------------
5126
}
5127
5128
// End of class
5129
// --------------------------------------------------------------------------------
5130
5131
// --------------------------------------------------------------------------------
5132
// Function : PclZipUtilPathReduction()
5133
// Description :
5134
// Parameters :
5135
// Return Values :
5136
// --------------------------------------------------------------------------------
5137
function PclZipUtilPathReduction($p_dir)
5138
{
5139
    $v_result = "";
5140
5141
    // ----- Look for not empty path
5142
    if ($p_dir != "") {
5143
        // ----- Explode path by directory names
5144
        $v_list = explode("/", $p_dir);
5145
5146
        // ----- Study directories from last to first
5147
        $v_skip = 0;
5148
        for ($i = sizeof($v_list) - 1; $i >= 0; $i--) {
5149
            // ----- Look for current path
5150
            if ($v_list[$i] == ".") {
5151
                // ----- Ignore this directory
5152
                // Should be the first $i=0, but no check is done
5153
            } elseif ($v_list[$i] == "..") {
5154
                $v_skip++;
5155
            } elseif ($v_list[$i] == "") {
5156
                // ----- First '/' i.e. root slash
5157
                if ($i == 0) {
5158
                    $v_result = "/" . $v_result;
5159
                    if ($v_skip > 0) {
5160
                        // ----- It is an invalid path, so the path is not modified
5161
                        // TBC
5162
                        $v_result = $p_dir;
5163
                        $v_skip   = 0;
5164
                    }
5165
5166
                // ----- Last '/' i.e. indicates a directory
5167
                } elseif ($i == (sizeof($v_list) - 1)) {
5168
                    $v_result = $v_list[$i];
5169
5170
                // ----- Double '/' inside the path
5171
                } else {
5172
                    // ----- Ignore only the double '//' in path,
5173
                    // but not the first and last '/'
5174
                }
5175
            } else {
5176
                // ----- Look for item to skip
5177
                if ($v_skip > 0) {
5178
                    $v_skip--;
5179
                } else {
5180
                    $v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? "/" . $v_result : "");
5181
                }
5182
            }
5183
        }
5184
5185
        // ----- Look for skip
5186
        if ($v_skip > 0) {
5187
            while ($v_skip > 0) {
5188
                $v_result = '../' . $v_result;
5189
                $v_skip--;
5190
            }
5191
        }
5192
    }
5193
5194
    // ----- Return
5195
    return $v_result;
5196
}
5197
// --------------------------------------------------------------------------------
5198
5199
// --------------------------------------------------------------------------------
5200
// Function : PclZipUtilPathInclusion()
5201
// Description :
5202
//   This function indicates if the path $p_path is under the $p_dir tree. Or,
5203
//   said in an other way, if the file or sub-dir $p_path is inside the dir
5204
//   $p_dir.
5205
//   The function indicates also if the path is exactly the same as the dir.
5206
//   This function supports path with duplicated '/' like '//', but does not
5207
//   support '.' or '..' statements.
5208
// Parameters :
5209
// Return Values :
5210
//   0 if $p_path is not inside directory $p_dir
5211
//   1 if $p_path is inside directory $p_dir
5212
//   2 if $p_path is exactly the same as $p_dir
5213
// --------------------------------------------------------------------------------
5214
function PclZipUtilPathInclusion($p_dir, $p_path)
5215
{
5216
    $v_result = 1;
5217
5218
    // ----- Look for path beginning by ./
5219
    if (($p_dir == '.') || ((strlen($p_dir) >= 2) && (substr($p_dir, 0, 2) == './'))) {
5220
        $p_dir = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_dir, 1);
5221
    }
5222
    if (($p_path == '.') || ((strlen($p_path) >= 2) && (substr($p_path, 0, 2) == './'))) {
5223
        $p_path = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_path, 1);
5224
    }
5225
5226
    // ----- Explode dir and path by directory separator
5227
    $v_list_dir       = explode("/", $p_dir);
5228
    $v_list_dir_size  = sizeof($v_list_dir);
5229
    $v_list_path      = explode("/", $p_path);
5230
    $v_list_path_size = sizeof($v_list_path);
5231
5232
    // ----- Study directories paths
5233
    $i = 0;
5234
    $j = 0;
5235
    while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5236
5237
        // ----- Look for empty dir (path reduction)
5238
        if ($v_list_dir[$i] == '') {
5239
            $i++;
5240
            continue;
5241
        }
5242
        if ($v_list_path[$j] == '') {
5243
            $j++;
5244
            continue;
5245
        }
5246
5247
        // ----- Compare the items
5248
        if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) {
5249
            $v_result = 0;
5250
        }
5251
5252
        // ----- Next items
5253
        $i++;
5254
        $j++;
5255
    }
5256
5257
    // ----- Look if everything seems to be the same
5258
    if ($v_result) {
5259
        // ----- Skip all the empty items
5260
        while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) {
5261
            $j++;
5262
        }
5263
        while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) {
5264
            $i++;
5265
        }
5266
5267
        if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5268
            // ----- There are exactly the same
5269
            $v_result = 2;
5270
        } elseif ($i < $v_list_dir_size) {
5271
            // ----- The path is shorter than the dir
5272
            $v_result = 0;
5273
        }
5274
    }
5275
5276
    // ----- Return
5277
    return $v_result;
5278
}
5279
// --------------------------------------------------------------------------------
5280
5281
// --------------------------------------------------------------------------------
5282
// Function : PclZipUtilCopyBlock()
5283
// Description :
5284
// Parameters :
5285
//   $p_mode : read/write compression mode
5286
//             0 : src & dest normal
5287
//             1 : src gzip, dest normal
5288
//             2 : src normal, dest gzip
5289
//             3 : src & dest gzip
5290
// Return Values :
5291
// --------------------------------------------------------------------------------
5292
function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode = 0)
5293
{
5294
    $v_result = 1;
5295
5296
    if ($p_mode == 0) {
5297
        while ($p_size != 0) {
5298
            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5299
            $v_buffer    = @fread($p_src, $v_read_size);
5300
            @fwrite($p_dest, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5300
            @fwrite($p_dest, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for fwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

5300
            /** @scrutinizer ignore-unhandled */ @fwrite($p_dest, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
5301
            $p_size -= $v_read_size;
5302
        }
5303
    } elseif ($p_mode == 1) {
5304
        while ($p_size != 0) {
5305
            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5306
            $v_buffer    = @gzread($p_src, $v_read_size);
5307
            @fwrite($p_dest, $v_buffer, $v_read_size);
5308
            $p_size -= $v_read_size;
5309
        }
5310
    } elseif ($p_mode == 2) {
5311
        while ($p_size != 0) {
5312
            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5313
            $v_buffer    = @fread($p_src, $v_read_size);
5314
            @gzwrite($p_dest, $v_buffer, $v_read_size);
0 ignored issues
show
Bug introduced by
It seems like $v_buffer can also be of type false; however, parameter $data of gzwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5314
            @gzwrite($p_dest, /** @scrutinizer ignore-type */ $v_buffer, $v_read_size);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for gzwrite(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

5314
            /** @scrutinizer ignore-unhandled */ @gzwrite($p_dest, $v_buffer, $v_read_size);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
5315
            $p_size -= $v_read_size;
5316
        }
5317
    } elseif ($p_mode == 3) {
5318
        while ($p_size != 0) {
5319
            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5320
            $v_buffer    = @gzread($p_src, $v_read_size);
5321
            @gzwrite($p_dest, $v_buffer, $v_read_size);
5322
            $p_size -= $v_read_size;
5323
        }
5324
    }
5325
5326
    // ----- Return
5327
    return $v_result;
5328
}
5329
// --------------------------------------------------------------------------------
5330
5331
// --------------------------------------------------------------------------------
5332
// Function : PclZipUtilRename()
5333
// Description :
5334
//   This function tries to do a simple rename() function. If it fails, it
5335
//   tries to copy the $p_src file in a new $p_dest file and then unlink the
5336
//   first one.
5337
// Parameters :
5338
//   $p_src : Old filename
5339
//   $p_dest : New filename
5340
// Return Values :
5341
//   1 on success, 0 on failure.
5342
// --------------------------------------------------------------------------------
5343
function PclZipUtilRename($p_src, $p_dest)
5344
{
5345
    $v_result = 1;
5346
5347
    // ----- Try to rename the files
5348
    if (!@rename($p_src, $p_dest)) {
5349
5350
        // ----- Try to copy & unlink the src
5351
        if (!@copy($p_src, $p_dest)) {
5352
            $v_result = 0;
5353
        } elseif (!@unlink($p_src)) {
5354
            $v_result = 0;
5355
        }
5356
    }
5357
5358
    // ----- Return
5359
    return $v_result;
5360
}
5361
// --------------------------------------------------------------------------------
5362
5363
// --------------------------------------------------------------------------------
5364
// Function : PclZipUtilOptionText()
5365
// Description :
5366
//   Translate option value in text. Mainly for debug purpose.
5367
// Parameters :
5368
//   $p_option : the option value.
5369
// Return Values :
5370
//   The option text value.
5371
// --------------------------------------------------------------------------------
5372
function PclZipUtilOptionText($p_option)
5373
{
5374
5375
    $v_list = get_defined_constants();
5376
    for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5377
        $v_prefix = substr($v_key, 0, 10);
5378
        if ((($v_prefix == 'PCLZIP_OPT') || ($v_prefix == 'PCLZIP_CB_') || ($v_prefix == 'PCLZIP_ATT')) && ($v_list[$v_key] == $p_option)) {
5379
            return $v_key;
5380
        }
5381
    }
5382
5383
    $v_result = 'Unknown';
5384
5385
    return $v_result;
5386
}
5387
// --------------------------------------------------------------------------------
5388
5389
// --------------------------------------------------------------------------------
5390
// Function : PclZipUtilTranslateWinPath()
5391
// Description :
5392
//   Translate windows path by replacing '\' by '/' and optionally removing
5393
//   drive letter.
5394
// Parameters :
5395
//   $p_path : path to translate.
5396
//   $p_remove_disk_letter : true | false
5397
// Return Values :
5398
//   The path translated.
5399
// --------------------------------------------------------------------------------
5400
function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter = true)
5401
{
5402
    if (stristr(php_uname(), 'windows')) {
5403
        // ----- Look for potential disk letter
5404
        if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $v_position = strpos($p_path, ':') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
5405
            $p_path = substr($p_path, $v_position + 1);
5406
        }
5407
        // ----- Change potential windows directory separator
5408
        if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) {
5409
            $p_path = strtr($p_path, '\\', '/');
5410
        }
5411
    }
5412
5413
    return $p_path;
5414
}
5415
// --------------------------------------------------------------------------------