PclZip::privParseOptions()   F
last analyzed

Complexity

Conditions 63
Paths 209

Size

Total Lines 392
Code Lines 181

Duplication

Lines 103
Ratio 26.28 %

Importance

Changes 0
Metric Value
cc 63
eloc 181
nc 209
nop 4
dl 103
loc 392
rs 3.88
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
    var $zipname = '';
194
195
    // ----- File descriptor of the zip file
196
    var $zip_fd = 0;
197
198
    // ----- Internal error handling
199
    var $error_code = 1;
200
    var $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
    var $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
  function __construct($p_zipname)
216
  {
217
218
    // ----- Tests the zlib
219
    if (!function_exists('gzopen'))
220
    {
221
      die('Abort '.basename(__FILE__).' : Missing zlib extensions');
0 ignored issues
show
Coding Style Compatibility introduced by
The method __construct() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
222
    }
223
224
    // ----- Set the attributes
225
    $this->zipname = $p_zipname;
226
    $this->zip_fd = 0;
227
    $this->magic_quotes_status = -1;
228
229
    // ----- Return
230
    return;
231
  }
232
233
  public function PclZip($p_zipname) {
234
    self::__construct($p_zipname);
235
  }
236
  // --------------------------------------------------------------------------------
237
238
  // --------------------------------------------------------------------------------
239
  // Function :
240
  //   create($p_filelist, $p_add_dir="", $p_remove_dir="")
241
  //   create($p_filelist, $p_option, $p_option_value, ...)
242
  // Description :
243
  //   This method supports two different synopsis. The first one is historical.
244
  //   This method creates a Zip Archive. The Zip file is created in the
245
  //   filesystem. The files and directories indicated in $p_filelist
246
  //   are added in the archive. See the parameters description for the
247
  //   supported format of $p_filelist.
248
  //   When a directory is in the list, the directory and its content is added
249
  //   in the archive.
250
  //   In this synopsis, the function takes an optional variable list of
251
  //   options. See bellow the supported options.
252
  // Parameters :
253
  //   $p_filelist : An array containing file or directory names, or
254
  //                 a string containing one filename or one directory name, or
255
  //                 a string containing a list of filenames and/or directory
256
  //                 names separated by spaces.
257
  //   $p_add_dir : A path to add before the real path of the archived file,
258
  //                in order to have it memorized in the archive.
259
  //   $p_remove_dir : A path to remove from the real path of the file to archive,
260
  //                   in order to have a shorter path memorized in the archive.
261
  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
262
  //                   is removed first, before $p_add_dir is added.
263
  // Options :
264
  //   PCLZIP_OPT_ADD_PATH :
265
  //   PCLZIP_OPT_REMOVE_PATH :
266
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
267
  //   PCLZIP_OPT_COMMENT :
268
  //   PCLZIP_CB_PRE_ADD :
269
  //   PCLZIP_CB_POST_ADD :
270
  // Return Values :
271
  //   0 on failure,
272
  //   The list of the added files, with a status of the add action.
273
  //   (see PclZip::listContent() for list entry format)
274
  // --------------------------------------------------------------------------------
275
  function create($p_filelist)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
276
  {
277
    $v_result=1;
278
279
    // ----- Reset the error handler
280
    $this->privErrorReset();
281
282
    // ----- Set default values
283
    $v_options = array();
284
    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
285
286
    // ----- Look for variable options arguments
287
    $v_size = func_num_args();
288
289
    // ----- Look for arguments
290
    if ($v_size > 1) {
291
      // ----- Get the arguments
292
      $v_arg_list = func_get_args();
293
294
      // ----- Remove from the options list the first argument
295
      array_shift($v_arg_list);
296
      $v_size--;
297
298
      // ----- Look for first arg
299
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
300
301
        // ----- Parse the options
302
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
303
                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
304
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
305
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
306
                                                   PCLZIP_CB_PRE_ADD => 'optional',
307
                                                   PCLZIP_CB_POST_ADD => 'optional',
308
                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
309
                                                   PCLZIP_OPT_COMMENT => 'optional',
310
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
311
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
312
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
313
                                                   //, PCLZIP_OPT_CRYPT => 'optional'
314
                                             ));
315
        if ($v_result != 1) {
316
          return 0;
317
        }
318
      }
319
320
      // ----- Look for 2 args
321
      // Here we need to support the first historic synopsis of the
322
      // method.
323 View Code Duplication
      else {
324
325
        // ----- Get the first argument
326
        $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
327
328
        // ----- Look for the optional second argument
329
        if ($v_size == 2) {
330
          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
331
        }
332
        else if ($v_size > 2) {
333
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
334
		                       "Invalid number / type of arguments");
335
          return 0;
336
        }
337
      }
338
    }
339
340
    // ----- Look for default option values
341
    $this->privOptionDefaultThreshold($v_options);
342
343
    // ----- Init
344
    $v_string_list = array();
345
    $v_att_list = array();
346
    $v_filedescr_list = array();
347
    $p_result_list = array();
348
349
    // ----- Look if the $p_filelist is really an array
350 View Code Duplication
    if (is_array($p_filelist)) {
351
352
      // ----- Look if the first element is also an array
353
      //       This will mean that this is a file description entry
354
      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
355
        $v_att_list = $p_filelist;
356
      }
357
358
      // ----- The list is a list of string names
359
      else {
360
        $v_string_list = $p_filelist;
361
      }
362
    }
363
364
    // ----- Look if the $p_filelist is a string
365
    else if (is_string($p_filelist)) {
366
      // ----- Create a list from the string
367
      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
368
    }
369
370
    // ----- Invalid variable type for $p_filelist
371
    else {
372
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
373
      return 0;
374
    }
375
376
    // ----- Reformat the string list
377 View Code Duplication
    if (sizeof($v_string_list) != 0) {
378
      foreach ($v_string_list as $v_string) {
379
        if ($v_string != '') {
380
          $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
381
        }
382
        else {
383
        }
384
      }
385
    }
386
387
    // ----- For each file in the list check the attributes
388
    $v_supported_attributes
389
    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
390
             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
391
             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
392
             ,PCLZIP_ATT_FILE_MTIME => 'optional'
393
             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
394
             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
395
						);
396 View Code Duplication
    foreach ($v_att_list as $v_entry) {
397
      $v_result = $this->privFileDescrParseAtt($v_entry,
398
                                               $v_filedescr_list[],
399
                                               $v_options,
400
                                               $v_supported_attributes);
401
      if ($v_result != 1) {
402
        return 0;
403
      }
404
    }
405
406
    // ----- Expand the filelist (expand directories)
407
    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
408
    if ($v_result != 1) {
409
      return 0;
410
    }
411
412
    // ----- Call the create fct
413
    $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
414
    if ($v_result != 1) {
415
      return 0;
416
    }
417
418
    // ----- Return
419
    return $p_result_list;
420
  }
421
  // --------------------------------------------------------------------------------
422
423
  // --------------------------------------------------------------------------------
424
  // Function :
425
  //   add($p_filelist, $p_add_dir="", $p_remove_dir="")
426
  //   add($p_filelist, $p_option, $p_option_value, ...)
427
  // Description :
428
  //   This method supports two synopsis. The first one is historical.
429
  //   This methods add the list of files in an existing archive.
430
  //   If a file with the same name already exists, it is added at the end of the
431
  //   archive, the first one is still present.
432
  //   If the archive does not exist, it is created.
433
  // Parameters :
434
  //   $p_filelist : An array containing file or directory names, or
435
  //                 a string containing one filename or one directory name, or
436
  //                 a string containing a list of filenames and/or directory
437
  //                 names separated by spaces.
438
  //   $p_add_dir : A path to add before the real path of the archived file,
439
  //                in order to have it memorized in the archive.
440
  //   $p_remove_dir : A path to remove from the real path of the file to archive,
441
  //                   in order to have a shorter path memorized in the archive.
442
  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
443
  //                   is removed first, before $p_add_dir is added.
444
  // Options :
445
  //   PCLZIP_OPT_ADD_PATH :
446
  //   PCLZIP_OPT_REMOVE_PATH :
447
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
448
  //   PCLZIP_OPT_COMMENT :
449
  //   PCLZIP_OPT_ADD_COMMENT :
450
  //   PCLZIP_OPT_PREPEND_COMMENT :
451
  //   PCLZIP_CB_PRE_ADD :
452
  //   PCLZIP_CB_POST_ADD :
453
  // Return Values :
454
  //   0 on failure,
455
  //   The list of the added files, with a status of the add action.
456
  //   (see PclZip::listContent() for list entry format)
457
  // --------------------------------------------------------------------------------
458
  function add($p_filelist)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
459
  {
460
    $v_result=1;
461
462
    // ----- Reset the error handler
463
    $this->privErrorReset();
464
465
    // ----- Set default values
466
    $v_options = array();
467
    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
468
469
    // ----- Look for variable options arguments
470
    $v_size = func_num_args();
471
472
    // ----- Look for arguments
473
    if ($v_size > 1) {
474
      // ----- Get the arguments
475
      $v_arg_list = func_get_args();
476
477
      // ----- Remove form the options list the first argument
478
      array_shift($v_arg_list);
479
      $v_size--;
480
481
      // ----- Look for first arg
482
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
483
484
        // ----- Parse the options
485
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
486
                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
487
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
488
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
489
                                                   PCLZIP_CB_PRE_ADD => 'optional',
490
                                                   PCLZIP_CB_POST_ADD => 'optional',
491
                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
492
                                                   PCLZIP_OPT_COMMENT => 'optional',
493
                                                   PCLZIP_OPT_ADD_COMMENT => 'optional',
494
                                                   PCLZIP_OPT_PREPEND_COMMENT => 'optional',
495
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
496
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
497
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
498
                                                   //, PCLZIP_OPT_CRYPT => 'optional'
499
												   ));
500
        if ($v_result != 1) {
501
          return 0;
502
        }
503
      }
504
505
      // ----- Look for 2 args
506
      // Here we need to support the first historic synopsis of the
507
      // method.
508 View Code Duplication
      else {
509
510
        // ----- Get the first argument
511
        $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
512
513
        // ----- Look for the optional second argument
514
        if ($v_size == 2) {
515
          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
516
        }
517
        else if ($v_size > 2) {
518
          // ----- Error log
519
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
520
521
          // ----- Return
522
          return 0;
523
        }
524
      }
525
    }
526
527
    // ----- Look for default option values
528
    $this->privOptionDefaultThreshold($v_options);
529
530
    // ----- Init
531
    $v_string_list = array();
532
    $v_att_list = array();
533
    $v_filedescr_list = array();
534
    $p_result_list = array();
535
536
    // ----- Look if the $p_filelist is really an array
537 View Code Duplication
    if (is_array($p_filelist)) {
538
539
      // ----- Look if the first element is also an array
540
      //       This will mean that this is a file description entry
541
      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
542
        $v_att_list = $p_filelist;
543
      }
544
545
      // ----- The list is a list of string names
546
      else {
547
        $v_string_list = $p_filelist;
548
      }
549
    }
550
551
    // ----- Look if the $p_filelist is a string
552
    else if (is_string($p_filelist)) {
553
      // ----- Create a list from the string
554
      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
555
    }
556
557
    // ----- Invalid variable type for $p_filelist
558
    else {
559
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
560
      return 0;
561
    }
562
563
    // ----- Reformat the string list
564 View Code Duplication
    if (sizeof($v_string_list) != 0) {
565
      foreach ($v_string_list as $v_string) {
566
        $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
567
      }
568
    }
569
570
    // ----- For each file in the list check the attributes
571
    $v_supported_attributes
572
    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
573
             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
574
             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
575
             ,PCLZIP_ATT_FILE_MTIME => 'optional'
576
             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
577
             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
578
						);
579 View Code Duplication
    foreach ($v_att_list as $v_entry) {
580
      $v_result = $this->privFileDescrParseAtt($v_entry,
581
                                               $v_filedescr_list[],
582
                                               $v_options,
583
                                               $v_supported_attributes);
584
      if ($v_result != 1) {
585
        return 0;
586
      }
587
    }
588
589
    // ----- Expand the filelist (expand directories)
590
    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
591
    if ($v_result != 1) {
592
      return 0;
593
    }
594
595
    // ----- Call the create fct
596
    $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
597
    if ($v_result != 1) {
598
      return 0;
599
    }
600
601
    // ----- Return
602
    return $p_result_list;
603
  }
604
  // --------------------------------------------------------------------------------
605
606
  // --------------------------------------------------------------------------------
607
  // Function : listContent()
608
  // Description :
609
  //   This public method, gives the list of the files and directories, with their
610
  //   properties.
611
  //   The properties of each entries in the list are (used also in other functions) :
612
  //     filename : Name of the file. For a create or add action it is the filename
613
  //                given by the user. For an extract function it is the filename
614
  //                of the extracted file.
615
  //     stored_filename : Name of the file / directory stored in the archive.
616
  //     size : Size of the stored file.
617
  //     compressed_size : Size of the file's data compressed in the archive
618
  //                       (without the headers overhead)
619
  //     mtime : Last known modification date of the file (UNIX timestamp)
620
  //     comment : Comment associated with the file
621
  //     folder : true | false
622
  //     index : index of the file in the archive
623
  //     status : status of the action (depending of the action) :
624
  //              Values are :
625
  //                ok : OK !
626
  //                filtered : the file / dir is not extracted (filtered by user)
627
  //                already_a_directory : the file can not be extracted because a
628
  //                                      directory with the same name already exists
629
  //                write_protected : the file can not be extracted because a file
630
  //                                  with the same name already exists and is
631
  //                                  write protected
632
  //                newer_exist : the file was not extracted because a newer file exists
633
  //                path_creation_fail : the file is not extracted because the folder
634
  //                                     does not exist and can not be created
635
  //                write_error : the file was not extracted because there was a
636
  //                              error while writing the file
637
  //                read_error : the file was not extracted because there was a error
638
  //                             while reading the file
639
  //                invalid_header : the file was not extracted because of an archive
640
  //                                 format error (bad file header)
641
  //   Note that each time a method can continue operating when there
642
  //   is an action error on a file, the error is only logged in the file status.
643
  // Return Values :
644
  //   0 on an unrecoverable failure,
645
  //   The list of the files in the archive.
646
  // --------------------------------------------------------------------------------
647
  function listContent()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
648
  {
649
    $v_result=1;
650
651
    // ----- Reset the error handler
652
    $this->privErrorReset();
653
654
    // ----- Check archive
655
    if (!$this->privCheckFormat()) {
656
      return(0);
657
    }
658
659
    // ----- Call the extracting fct
660
    $p_list = array();
661
    if (($v_result = $this->privList($p_list)) != 1)
662
    {
663
      unset($p_list);
664
      return(0);
665
    }
666
667
    // ----- Return
668
    return $p_list;
669
  }
670
  // --------------------------------------------------------------------------------
671
672
  // --------------------------------------------------------------------------------
673
  // Function :
674
  //   extract($p_path="./", $p_remove_path="")
675
  //   extract([$p_option, $p_option_value, ...])
676
  // Description :
677
  //   This method supports two synopsis. The first one is historical.
678
  //   This method extract all the files / directories from the archive to the
679
  //   folder indicated in $p_path.
680
  //   If you want to ignore the 'root' part of path of the memorized files
681
  //   you can indicate this in the optional $p_remove_path parameter.
682
  //   By default, if a newer file with the same name already exists, the
683
  //   file is not extracted.
684
  //
685
  //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
686
  //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
687
  //   at the end of the path value of PCLZIP_OPT_PATH.
688
  // Parameters :
689
  //   $p_path : Path where the files and directories are to be extracted
690
  //   $p_remove_path : First part ('root' part) of the memorized path
691
  //                    (if any similar) to remove while extracting.
692
  // Options :
693
  //   PCLZIP_OPT_PATH :
694
  //   PCLZIP_OPT_ADD_PATH :
695
  //   PCLZIP_OPT_REMOVE_PATH :
696
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
697
  //   PCLZIP_CB_PRE_EXTRACT :
698
  //   PCLZIP_CB_POST_EXTRACT :
699
  // Return Values :
700
  //   0 or a negative value on failure,
701
  //   The list of the extracted files, with a status of the action.
702
  //   (see PclZip::listContent() for list entry format)
703
  // --------------------------------------------------------------------------------
704
  function extract()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
705
  {
706
    $v_result=1;
707
708
    // ----- Reset the error handler
709
    $this->privErrorReset();
710
711
    // ----- Check archive
712
    if (!$this->privCheckFormat()) {
713
      return(0);
714
    }
715
716
    // ----- Set default values
717
    $v_options = array();
718
//    $v_path = "./";
719
    $v_path = '';
720
    $v_remove_path = "";
721
    $v_remove_all_path = false;
722
723
    // ----- Look for variable options arguments
724
    $v_size = func_num_args();
725
726
    // ----- Default values for option
727
    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
728
729
    // ----- Look for arguments
730
    if ($v_size > 0) {
731
      // ----- Get the arguments
732
      $v_arg_list = func_get_args();
733
734
      // ----- Look for first arg
735
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
736
737
        // ----- Parse the options
738
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
739
                                            array (PCLZIP_OPT_PATH => 'optional',
740
                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
741
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
742
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
743
                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
744
                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
745
                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
746
                                                   PCLZIP_OPT_BY_NAME => 'optional',
747
                                                   PCLZIP_OPT_BY_EREG => 'optional',
748
                                                   PCLZIP_OPT_BY_PREG => 'optional',
749
                                                   PCLZIP_OPT_BY_INDEX => 'optional',
750
                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
751
                                                   PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
752
                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
753
                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
754
                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
755
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
756
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
757
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
758
												    ));
759
        if ($v_result != 1) {
760
          return 0;
761
        }
762
763
        // ----- Set the arguments
764
        if (isset($v_options[PCLZIP_OPT_PATH])) {
765
          $v_path = $v_options[PCLZIP_OPT_PATH];
766
        }
767
        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
768
          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
769
        }
770
        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
771
          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
772
        }
773 View Code Duplication
        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
774
          // ----- Check for '/' in last path char
775
          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
776
            $v_path .= '/';
777
          }
778
          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
779
        }
780
      }
781
782
      // ----- Look for 2 args
783
      // Here we need to support the first historic synopsis of the
784
      // method.
785
      else {
786
787
        // ----- Get the first argument
788
        $v_path = $v_arg_list[0];
789
790
        // ----- Look for the optional second argument
791
        if ($v_size == 2) {
792
          $v_remove_path = $v_arg_list[1];
793
        }
794
        else if ($v_size > 2) {
795
          // ----- Error log
796
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
797
798
          // ----- Return
799
          return 0;
800
        }
801
      }
802
    }
803
804
    // ----- Look for default option values
805
    $this->privOptionDefaultThreshold($v_options);
806
807
    // ----- Trace
808
809
    // ----- Call the extracting fct
810
    $p_list = array();
811
    $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
812
	                                     $v_remove_all_path, $v_options);
813
    if ($v_result < 1) {
814
      unset($p_list);
815
      return(0);
816
    }
817
818
    // ----- Return
819
    return $p_list;
820
  }
821
  // --------------------------------------------------------------------------------
822
823
824
  // --------------------------------------------------------------------------------
825
  // Function :
826
  //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
827
  //   extractByIndex($p_index, [$p_option, $p_option_value, ...])
828
  // Description :
829
  //   This method supports two synopsis. The first one is historical.
830
  //   This method is doing a partial extract of the archive.
831
  //   The extracted files or folders are identified by their index in the
832
  //   archive (from 0 to n).
833
  //   Note that if the index identify a folder, only the folder entry is
834
  //   extracted, not all the files included in the archive.
835
  // Parameters :
836
  //   $p_index : A single index (integer) or a string of indexes of files to
837
  //              extract. The form of the string is "0,4-6,8-12" with only numbers
838
  //              and '-' for range or ',' to separate ranges. No spaces or ';'
839
  //              are allowed.
840
  //   $p_path : Path where the files and directories are to be extracted
841
  //   $p_remove_path : First part ('root' part) of the memorized path
842
  //                    (if any similar) to remove while extracting.
843
  // Options :
844
  //   PCLZIP_OPT_PATH :
845
  //   PCLZIP_OPT_ADD_PATH :
846
  //   PCLZIP_OPT_REMOVE_PATH :
847
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
848
  //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
849
  //     not as files.
850
  //     The resulting content is in a new field 'content' in the file
851
  //     structure.
852
  //     This option must be used alone (any other options are ignored).
853
  //   PCLZIP_CB_PRE_EXTRACT :
854
  //   PCLZIP_CB_POST_EXTRACT :
855
  // Return Values :
856
  //   0 on failure,
857
  //   The list of the extracted files, with a status of the action.
858
  //   (see PclZip::listContent() for list entry format)
859
  // --------------------------------------------------------------------------------
860
  //function extractByIndex($p_index, options...)
861
  function extractByIndex($p_index)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
862
  {
863
    $v_result=1;
864
865
    // ----- Reset the error handler
866
    $this->privErrorReset();
867
868
    // ----- Check archive
869
    if (!$this->privCheckFormat()) {
870
      return(0);
871
    }
872
873
    // ----- Set default values
874
    $v_options = array();
875
//    $v_path = "./";
876
    $v_path = '';
877
    $v_remove_path = "";
878
    $v_remove_all_path = false;
879
880
    // ----- Look for variable options arguments
881
    $v_size = func_num_args();
882
883
    // ----- Default values for option
884
    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
885
886
    // ----- Look for arguments
887
    if ($v_size > 1) {
888
      // ----- Get the arguments
889
      $v_arg_list = func_get_args();
890
891
      // ----- Remove form the options list the first argument
892
      array_shift($v_arg_list);
893
      $v_size--;
894
895
      // ----- Look for first arg
896
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
897
898
        // ----- Parse the options
899
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
900
                                            array (PCLZIP_OPT_PATH => 'optional',
901
                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
902
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
903
                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
904
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
905
                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
906
                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
907
                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
908
                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
909
                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
910
                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
911
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
912
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
913
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
914
												   ));
915
        if ($v_result != 1) {
916
          return 0;
917
        }
918
919
        // ----- Set the arguments
920
        if (isset($v_options[PCLZIP_OPT_PATH])) {
921
          $v_path = $v_options[PCLZIP_OPT_PATH];
922
        }
923
        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
924
          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
925
        }
926
        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
927
          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
928
        }
929 View Code Duplication
        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
930
          // ----- Check for '/' in last path char
931
          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
932
            $v_path .= '/';
933
          }
934
          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
935
        }
936
        if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
937
          $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
938
        }
939
        else {
940
        }
941
      }
942
943
      // ----- Look for 2 args
944
      // Here we need to support the first historic synopsis of the
945
      // method.
946
      else {
947
948
        // ----- Get the first argument
949
        $v_path = $v_arg_list[0];
950
951
        // ----- Look for the optional second argument
952
        if ($v_size == 2) {
953
          $v_remove_path = $v_arg_list[1];
954
        }
955
        else if ($v_size > 2) {
956
          // ----- Error log
957
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
958
959
          // ----- Return
960
          return 0;
961
        }
962
      }
963
    }
964
965
    // ----- Trace
966
967
    // ----- Trick
968
    // Here I want to reuse extractByRule(), so I need to parse the $p_index
969
    // with privParseOptions()
970
    $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
971
    $v_options_trick = array();
972
    $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
973
                                        array (PCLZIP_OPT_BY_INDEX => 'optional' ));
974
    if ($v_result != 1) {
975
        return 0;
976
    }
977
    $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
978
979
    // ----- Look for default option values
980
    $this->privOptionDefaultThreshold($v_options);
981
982
    // ----- Call the extracting fct
983
    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
984
        return(0);
985
    }
986
987
    // ----- Return
988
    return $p_list;
989
  }
990
  // --------------------------------------------------------------------------------
991
992
  // --------------------------------------------------------------------------------
993
  // Function :
994
  //   delete([$p_option, $p_option_value, ...])
995
  // Description :
996
  //   This method removes files from the archive.
997
  //   If no parameters are given, then all the archive is emptied.
998
  // Parameters :
999
  //   None or optional arguments.
1000
  // Options :
1001
  //   PCLZIP_OPT_BY_INDEX :
1002
  //   PCLZIP_OPT_BY_NAME :
1003
  //   PCLZIP_OPT_BY_EREG :
1004
  //   PCLZIP_OPT_BY_PREG :
1005
  // Return Values :
1006
  //   0 on failure,
1007
  //   The list of the files which are still present in the archive.
1008
  //   (see PclZip::listContent() for list entry format)
1009
  // --------------------------------------------------------------------------------
1010
  function delete()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1011
  {
1012
    $v_result=1;
1013
1014
    // ----- Reset the error handler
1015
    $this->privErrorReset();
1016
1017
    // ----- Check archive
1018
    if (!$this->privCheckFormat()) {
1019
      return(0);
1020
    }
1021
1022
    // ----- Set default values
1023
    $v_options = array();
1024
1025
    // ----- Look for variable options arguments
1026
    $v_size = func_num_args();
1027
1028
    // ----- Look for arguments
1029
    if ($v_size > 0) {
1030
      // ----- Get the arguments
1031
      $v_arg_list = func_get_args();
1032
1033
      // ----- Parse the options
1034
      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1035
                                        array (PCLZIP_OPT_BY_NAME => 'optional',
1036
                                               PCLZIP_OPT_BY_EREG => 'optional',
1037
                                               PCLZIP_OPT_BY_PREG => 'optional',
1038
                                               PCLZIP_OPT_BY_INDEX => 'optional' ));
1039
      if ($v_result != 1) {
1040
          return 0;
1041
      }
1042
    }
1043
1044
    // ----- Magic quotes trick
1045
    $this->privDisableMagicQuotes();
1046
1047
    // ----- Call the delete fct
1048
    $v_list = array();
1049
    if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1050
      $this->privSwapBackMagicQuotes();
1051
      unset($v_list);
1052
      return(0);
1053
    }
1054
1055
    // ----- Magic quotes trick
1056
    $this->privSwapBackMagicQuotes();
1057
1058
    // ----- Return
1059
    return $v_list;
1060
  }
1061
  // --------------------------------------------------------------------------------
1062
1063
  // --------------------------------------------------------------------------------
1064
  // Function : deleteByIndex()
1065
  // Description :
1066
  //   ***** Deprecated *****
1067
  //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1068
  // --------------------------------------------------------------------------------
1069
  function deleteByIndex($p_index)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1070
  {
1071
1072
    $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1073
1074
    // ----- Return
1075
    return $p_list;
1076
  }
1077
  // --------------------------------------------------------------------------------
1078
1079
  // --------------------------------------------------------------------------------
1080
  // Function : properties()
1081
  // Description :
1082
  //   This method gives the properties of the archive.
1083
  //   The properties are :
1084
  //     nb : Number of files in the archive
1085
  //     comment : Comment associated with the archive file
1086
  //     status : not_exist, ok
1087
  // Parameters :
1088
  //   None
1089
  // Return Values :
1090
  //   0 on failure,
1091
  //   An array with the archive properties.
1092
  // --------------------------------------------------------------------------------
1093
  function properties()
1094
  {
1095
1096
    // ----- Reset the error handler
1097
    $this->privErrorReset();
1098
1099
    // ----- Magic quotes trick
1100
    $this->privDisableMagicQuotes();
1101
1102
    // ----- Check archive
1103
    if (!$this->privCheckFormat()) {
1104
      $this->privSwapBackMagicQuotes();
1105
      return(0);
1106
    }
1107
1108
    // ----- Default properties
1109
    $v_prop = array();
1110
    $v_prop['comment'] = '';
1111
    $v_prop['nb'] = 0;
1112
    $v_prop['status'] = 'not_exist';
1113
1114
    // ----- Look if file exists
1115
    if (@is_file($this->zipname))
1116
    {
1117
      // ----- Open the zip file
1118 View Code Duplication
      if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1119
      {
1120
        $this->privSwapBackMagicQuotes();
1121
1122
        // ----- Error log
1123
        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1124
1125
        // ----- Return
1126
        return 0;
1127
      }
1128
1129
      // ----- Read the central directory informations
1130
      $v_central_dir = array();
1131
      if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1132
      {
1133
        $this->privSwapBackMagicQuotes();
1134
        return 0;
1135
      }
1136
1137
      // ----- Close the zip file
1138
      $this->privCloseFd();
1139
1140
      // ----- Set the user attributes
1141
      $v_prop['comment'] = $v_central_dir['comment'];
1142
      $v_prop['nb'] = $v_central_dir['entries'];
1143
      $v_prop['status'] = 'ok';
1144
    }
1145
1146
    // ----- Magic quotes trick
1147
    $this->privSwapBackMagicQuotes();
1148
1149
    // ----- Return
1150
    return $v_prop;
1151
  }
1152
  // --------------------------------------------------------------------------------
1153
1154
  // --------------------------------------------------------------------------------
1155
  // Function : duplicate()
1156
  // Description :
1157
  //   This method creates an archive by copying the content of an other one. If
1158
  //   the archive already exist, it is replaced by the new one without any warning.
1159
  // Parameters :
1160
  //   $p_archive : The filename of a valid archive, or
1161
  //                a valid PclZip object.
1162
  // Return Values :
1163
  //   1 on success.
1164
  //   0 or a negative value on error (error code).
1165
  // --------------------------------------------------------------------------------
1166
  function duplicate($p_archive)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1167
  {
1168
    $v_result = 1;
1169
1170
    // ----- Reset the error handler
1171
    $this->privErrorReset();
1172
1173
    // ----- Look if the $p_archive is a PclZip object
1174
    if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1175
    {
1176
1177
      // ----- Duplicate the archive
1178
      $v_result = $this->privDuplicate($p_archive->zipname);
1179
    }
1180
1181
    // ----- Look if the $p_archive is a string (so a filename)
1182
    else if (is_string($p_archive))
1183
    {
1184
1185
      // ----- Check that $p_archive is a valid zip file
1186
      // TBC : Should also check the archive format
1187
      if (!is_file($p_archive)) {
1188
        // ----- Error log
1189
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1190
        $v_result = PCLZIP_ERR_MISSING_FILE;
1191
      }
1192
      else {
1193
        // ----- Duplicate the archive
1194
        $v_result = $this->privDuplicate($p_archive);
1195
      }
1196
    }
1197
1198
    // ----- Invalid variable
1199
    else
1200
    {
1201
      // ----- Error log
1202
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1203
      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1204
    }
1205
1206
    // ----- Return
1207
    return $v_result;
1208
  }
1209
  // --------------------------------------------------------------------------------
1210
1211
  // --------------------------------------------------------------------------------
1212
  // Function : merge()
1213
  // Description :
1214
  //   This method merge the $p_archive_to_add archive at the end of the current
1215
  //   one ($this).
1216
  //   If the archive ($this) does not exist, the merge becomes a duplicate.
1217
  //   If the $p_archive_to_add archive does not exist, the merge is a success.
1218
  // Parameters :
1219
  //   $p_archive_to_add : It can be directly the filename of a valid zip archive,
1220
  //                       or a PclZip object archive.
1221
  // Return Values :
1222
  //   1 on success,
1223
  //   0 or negative values on error (see below).
1224
  // --------------------------------------------------------------------------------
1225
  function merge($p_archive_to_add)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1226
  {
1227
    $v_result = 1;
1228
1229
    // ----- Reset the error handler
1230
    $this->privErrorReset();
1231
1232
    // ----- Check archive
1233
    if (!$this->privCheckFormat()) {
1234
      return(0);
1235
    }
1236
1237
    // ----- Look if the $p_archive_to_add is a PclZip object
1238
    if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1239
    {
1240
1241
      // ----- Merge the archive
1242
      $v_result = $this->privMerge($p_archive_to_add);
1243
    }
1244
1245
    // ----- Look if the $p_archive_to_add is a string (so a filename)
1246
    else if (is_string($p_archive_to_add))
1247
    {
1248
1249
      // ----- Create a temporary archive
1250
      $v_object_archive = new PclZip($p_archive_to_add);
1251
1252
      // ----- Merge the archive
1253
      $v_result = $this->privMerge($v_object_archive);
1254
    }
1255
1256
    // ----- Invalid variable
1257
    else
1258
    {
1259
      // ----- Error log
1260
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1261
      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1262
    }
1263
1264
    // ----- Return
1265
    return $v_result;
1266
  }
1267
  // --------------------------------------------------------------------------------
1268
1269
1270
1271
  // --------------------------------------------------------------------------------
1272
  // Function : errorCode()
1273
  // Description :
1274
  // Parameters :
1275
  // --------------------------------------------------------------------------------
1276
  function errorCode()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1277
  {
1278
    if (PCLZIP_ERROR_EXTERNAL == 1) {
1279
      return(PclErrorCode());
1280
    }
1281
    else {
1282
      return($this->error_code);
1283
    }
1284
  }
1285
  // --------------------------------------------------------------------------------
1286
1287
  // --------------------------------------------------------------------------------
1288
  // Function : errorName()
1289
  // Description :
1290
  // Parameters :
1291
  // --------------------------------------------------------------------------------
1292
  function errorName($p_with_code=false)
1293
  {
1294
    $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1295
                      PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1296
                      PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1297
                      PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1298
                      PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1299
                      PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1300
                      PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1301
                      PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1302
                      PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1303
                      PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1304
                      PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1305
                      PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1306
                      PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1307
                      PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1308
                      PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1309
                      PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1310
                      PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1311
                      PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1312
                      PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1313
                      ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1314
                      ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1315
                    );
1316
1317
    if (isset($v_name[$this->error_code])) {
1318
      $v_value = $v_name[$this->error_code];
1319
    }
1320
    else {
1321
      $v_value = 'NoName';
1322
    }
1323
1324
    if ($p_with_code) {
1325
      return($v_value.' ('.$this->error_code.')');
1326
    }
1327
    else {
1328
      return($v_value);
1329
    }
1330
  }
1331
  // --------------------------------------------------------------------------------
1332
1333
  // --------------------------------------------------------------------------------
1334
  // Function : errorInfo()
1335
  // Description :
1336
  // Parameters :
1337
  // --------------------------------------------------------------------------------
1338
  function errorInfo($p_full=false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1339
  {
1340
    if (PCLZIP_ERROR_EXTERNAL == 1) {
1341
      return(PclErrorString());
1342
    }
1343
    else {
1344
      if ($p_full) {
1345
        return($this->errorName(true)." : ".$this->error_string);
1346
      }
1347
      else {
1348
        return($this->error_string." [code ".$this->error_code."]");
1349
      }
1350
    }
1351
  }
1352
  // --------------------------------------------------------------------------------
1353
1354
1355
// --------------------------------------------------------------------------------
1356
// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1357
// *****                                                        *****
1358
// *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
1359
// --------------------------------------------------------------------------------
1360
1361
1362
1363
  // --------------------------------------------------------------------------------
1364
  // Function : privCheckFormat()
1365
  // Description :
1366
  //   This method check that the archive exists and is a valid zip archive.
1367
  //   Several level of check exists. (futur)
1368
  // Parameters :
1369
  //   $p_level : Level of check. Default 0.
1370
  //              0 : Check the first bytes (magic codes) (default value))
1371
  //              1 : 0 + Check the central directory (futur)
1372
  //              2 : 1 + Check each file header (futur)
1373
  // Return Values :
1374
  //   true on success,
1375
  //   false on error, the error code is set.
1376
  // --------------------------------------------------------------------------------
1377
  function privCheckFormat($p_level=0)
0 ignored issues
show
Unused Code introduced by
The parameter $p_level is not used and could be removed.

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

Loading history...
1378
  {
1379
    $v_result = true;
1380
1381
	// ----- Reset the file system cache
1382
    clearstatcache();
1383
1384
    // ----- Reset the error handler
1385
    $this->privErrorReset();
1386
1387
    // ----- Look if the file exits
1388
    if (!is_file($this->zipname)) {
1389
      // ----- Error log
1390
      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1391
      return(false);
1392
    }
1393
1394
    // ----- Check that the file is readeable
1395
    if (!is_readable($this->zipname)) {
1396
      // ----- Error log
1397
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1398
      return(false);
1399
    }
1400
1401
    // ----- Check the magic code
1402
    // TBC
1403
1404
    // ----- Check the central header
1405
    // TBC
1406
1407
    // ----- Check each file header
1408
    // TBC
1409
1410
    // ----- Return
1411
    return $v_result;
1412
  }
1413
  // --------------------------------------------------------------------------------
1414
1415
  // --------------------------------------------------------------------------------
1416
  // Function : privParseOptions()
1417
  // Description :
1418
  //   This internal methods reads the variable list of arguments ($p_options_list,
1419
  //   $p_size) and generate an array with the options and values ($v_result_list).
1420
  //   $v_requested_options contains the options that can be present and those that
1421
  //   must be present.
1422
  //   $v_requested_options is an array, with the option value as key, and 'optional',
1423
  //   or 'mandatory' as value.
1424
  // Parameters :
1425
  //   See above.
1426
  // Return Values :
1427
  //   1 on success.
1428
  //   0 on failure.
1429
  // --------------------------------------------------------------------------------
1430
  function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1431
  {
1432
    $v_result=1;
1433
1434
    // ----- Read the options
1435
    $i=0;
1436
    while ($i<$p_size) {
1437
1438
      // ----- Check if the option is supported
1439 View Code Duplication
      if (!isset($v_requested_options[$p_options_list[$i]])) {
1440
        // ----- Error log
1441
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1442
1443
        // ----- Return
1444
        return PclZip::errorCode();
1445
      }
1446
1447
      // ----- Look for next option
1448
      switch ($p_options_list[$i]) {
1449
        // ----- Look for options that request a path value
1450
        case PCLZIP_OPT_PATH :
1451
        case PCLZIP_OPT_REMOVE_PATH :
1452 View Code Duplication
        case PCLZIP_OPT_ADD_PATH :
1453
          // ----- Check the number of parameters
1454
          if (($i+1) >= $p_size) {
1455
            // ----- Error log
1456
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1457
1458
            // ----- Return
1459
            return PclZip::errorCode();
1460
          }
1461
1462
          // ----- Get the value
1463
          $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1464
          $i++;
1465
        break;
1466
1467
        case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
1468
          // ----- Check the number of parameters
1469
          if (($i+1) >= $p_size) {
1470
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1471
            return PclZip::errorCode();
1472
          }
1473
1474
          // ----- Check for incompatible options
1475
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1476
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1477
            return PclZip::errorCode();
1478
          }
1479
1480
          // ----- Check the value
1481
          $v_value = $p_options_list[$i+1];
1482
          if ((!is_integer($v_value)) || ($v_value<0)) {
1483
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1484
            return PclZip::errorCode();
1485
          }
1486
1487
          // ----- Get the value (and convert it in bytes)
1488
          $v_result_list[$p_options_list[$i]] = $v_value*1048576;
1489
          $i++;
1490
        break;
1491
1492
        case PCLZIP_OPT_TEMP_FILE_ON :
1493
          // ----- Check for incompatible options
1494
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1495
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1496
            return PclZip::errorCode();
1497
          }
1498
1499
          $v_result_list[$p_options_list[$i]] = true;
1500
        break;
1501
1502
        case PCLZIP_OPT_TEMP_FILE_OFF :
1503
          // ----- Check for incompatible options
1504
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1505
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1506
            return PclZip::errorCode();
1507
          }
1508
          // ----- Check for incompatible options
1509
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1510
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1511
            return PclZip::errorCode();
1512
          }
1513
1514
          $v_result_list[$p_options_list[$i]] = true;
1515
        break;
1516
1517
        case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1518
          // ----- Check the number of parameters
1519
          if (($i+1) >= $p_size) {
1520
            // ----- Error log
1521
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1522
1523
            // ----- Return
1524
            return PclZip::errorCode();
1525
          }
1526
1527
          // ----- Get the value
1528
          if (   is_string($p_options_list[$i+1])
1529
              && ($p_options_list[$i+1] != '')) {
1530
            $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1531
            $i++;
1532
          }
1533
          else {
1534
          }
1535
        break;
1536
1537
        // ----- Look for options that request an array of string for value
1538
        case PCLZIP_OPT_BY_NAME :
1539
          // ----- Check the number of parameters
1540
          if (($i+1) >= $p_size) {
1541
            // ----- Error log
1542
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1543
1544
            // ----- Return
1545
            return PclZip::errorCode();
1546
          }
1547
1548
          // ----- Get the value
1549
          if (is_string($p_options_list[$i+1])) {
1550
              $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1551
          }
1552
          else if (is_array($p_options_list[$i+1])) {
1553
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1554
          }
1555
          else {
1556
            // ----- Error log
1557
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1558
1559
            // ----- Return
1560
            return PclZip::errorCode();
1561
          }
1562
          $i++;
1563
        break;
1564
1565
        // ----- Look for options that request an EREG or PREG expression
1566
        case PCLZIP_OPT_BY_EREG :
1567
          // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
1568
          // to PCLZIP_OPT_BY_PREG
1569
          $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1570 View Code Duplication
        case PCLZIP_OPT_BY_PREG :
1571
        //case PCLZIP_OPT_CRYPT :
1572
          // ----- Check the number of parameters
1573
          if (($i+1) >= $p_size) {
1574
            // ----- Error log
1575
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1576
1577
            // ----- Return
1578
            return PclZip::errorCode();
1579
          }
1580
1581
          // ----- Get the value
1582
          if (is_string($p_options_list[$i+1])) {
1583
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1584
          }
1585
          else {
1586
            // ----- Error log
1587
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1588
1589
            // ----- Return
1590
            return PclZip::errorCode();
1591
          }
1592
          $i++;
1593
        break;
1594
1595
        // ----- Look for options that takes a string
1596
        case PCLZIP_OPT_COMMENT :
1597
        case PCLZIP_OPT_ADD_COMMENT :
1598 View Code Duplication
        case PCLZIP_OPT_PREPEND_COMMENT :
1599
          // ----- Check the number of parameters
1600
          if (($i+1) >= $p_size) {
1601
            // ----- Error log
1602
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1603
			                     "Missing parameter value for option '"
1604
								 .PclZipUtilOptionText($p_options_list[$i])
1605
								 ."'");
1606
1607
            // ----- Return
1608
            return PclZip::errorCode();
1609
          }
1610
1611
          // ----- Get the value
1612
          if (is_string($p_options_list[$i+1])) {
1613
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1614
          }
1615
          else {
1616
            // ----- Error log
1617
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1618
			                     "Wrong parameter value for option '"
1619
								 .PclZipUtilOptionText($p_options_list[$i])
1620
								 ."'");
1621
1622
            // ----- Return
1623
            return PclZip::errorCode();
1624
          }
1625
          $i++;
1626
        break;
1627
1628
        // ----- Look for options that request an array of index
1629
        case PCLZIP_OPT_BY_INDEX :
1630
          // ----- Check the number of parameters
1631
          if (($i+1) >= $p_size) {
1632
            // ----- Error log
1633
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1634
1635
            // ----- Return
1636
            return PclZip::errorCode();
1637
          }
1638
1639
          // ----- Get the value
1640
          $v_work_list = array();
1641
          if (is_string($p_options_list[$i+1])) {
1642
1643
              // ----- Remove spaces
1644
              $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1645
1646
              // ----- Parse items
1647
              $v_work_list = explode(",", $p_options_list[$i+1]);
1648
          }
1649
          else if (is_integer($p_options_list[$i+1])) {
1650
              $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1651
          }
1652
          else if (is_array($p_options_list[$i+1])) {
1653
              $v_work_list = $p_options_list[$i+1];
1654
          }
1655
          else {
1656
            // ----- Error log
1657
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1658
1659
            // ----- Return
1660
            return PclZip::errorCode();
1661
          }
1662
1663
          // ----- Reduce the index list
1664
          // each index item in the list must be a couple with a start and
1665
          // an end value : [0,3], [5-5], [8-10], ...
1666
          // ----- Check the format of each item
1667
          $v_sort_flag=false;
1668
          $v_sort_value=0;
1669
          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...
1670
              // ----- Explode the item
1671
              $v_item_list = explode("-", $v_work_list[$j]);
1672
              $v_size_item_list = sizeof($v_item_list);
1673
1674
              // ----- TBC : Here we might check that each item is a
1675
              // real integer ...
1676
1677
              // ----- Look for single value
1678
              if ($v_size_item_list == 1) {
1679
                  // ----- Set the option value
1680
                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1681
                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1682
              }
1683
              elseif ($v_size_item_list == 2) {
1684
                  // ----- Set the option value
1685
                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1686
                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1687
              }
1688
              else {
1689
                  // ----- Error log
1690
                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1691
1692
                  // ----- Return
1693
                  return PclZip::errorCode();
1694
              }
1695
1696
1697
              // ----- Look for list sort
1698
              if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1699
                  $v_sort_flag=true;
1700
1701
                  // ----- TBC : An automatic sort should be writen ...
1702
                  // ----- Error log
1703
                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1704
1705
                  // ----- Return
1706
                  return PclZip::errorCode();
1707
              }
1708
              $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1709
          }
1710
1711
          // ----- Sort the items
1712
          if ($v_sort_flag) {
1713
              // TBC : To Be Completed
1714
          }
1715
1716
          // ----- Next option
1717
          $i++;
1718
        break;
1719
1720
        // ----- Look for options that request no value
1721
        case PCLZIP_OPT_REMOVE_ALL_PATH :
1722
        case PCLZIP_OPT_EXTRACT_AS_STRING :
1723
        case PCLZIP_OPT_NO_COMPRESSION :
1724
        case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1725
        case PCLZIP_OPT_REPLACE_NEWER :
1726
        case PCLZIP_OPT_STOP_ON_ERROR :
1727
          $v_result_list[$p_options_list[$i]] = true;
1728
        break;
1729
1730
        // ----- Look for options that request an octal value
1731 View Code Duplication
        case PCLZIP_OPT_SET_CHMOD :
1732
          // ----- Check the number of parameters
1733
          if (($i+1) >= $p_size) {
1734
            // ----- Error log
1735
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1736
1737
            // ----- Return
1738
            return PclZip::errorCode();
1739
          }
1740
1741
          // ----- Get the value
1742
          $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1743
          $i++;
1744
        break;
1745
1746
        // ----- Look for options that request a call-back
1747
        case PCLZIP_CB_PRE_EXTRACT :
1748
        case PCLZIP_CB_POST_EXTRACT :
1749
        case PCLZIP_CB_PRE_ADD :
1750
        case PCLZIP_CB_POST_ADD :
1751
        /* for futur use
1752
        case PCLZIP_CB_PRE_DELETE :
1753
        case PCLZIP_CB_POST_DELETE :
1754
        case PCLZIP_CB_PRE_LIST :
1755
        case PCLZIP_CB_POST_LIST :
1756
        */
1757
          // ----- Check the number of parameters
1758
          if (($i+1) >= $p_size) {
1759
            // ----- Error log
1760
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1761
1762
            // ----- Return
1763
            return PclZip::errorCode();
1764
          }
1765
1766
          // ----- Get the value
1767
          $v_function_name = $p_options_list[$i+1];
1768
1769
          // ----- Check that the value is a valid existing function
1770
          if (!function_exists($v_function_name)) {
1771
            // ----- Error log
1772
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1773
1774
            // ----- Return
1775
            return PclZip::errorCode();
1776
          }
1777
1778
          // ----- Set the attribute
1779
          $v_result_list[$p_options_list[$i]] = $v_function_name;
1780
          $i++;
1781
        break;
1782
1783
        default :
1784
          // ----- Error log
1785
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1786
		                       "Unknown parameter '"
1787
							   .$p_options_list[$i]."'");
1788
1789
          // ----- Return
1790
          return PclZip::errorCode();
1791
      }
1792
1793
      // ----- Next options
1794
      $i++;
1795
    }
1796
1797
    // ----- Look for mandatory options
1798 View Code Duplication
    if ($v_requested_options !== false) {
1799
      for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1800
        // ----- Look for mandatory option
1801
        if ($v_requested_options[$key] == 'mandatory') {
1802
          // ----- Look if present
1803
          if (!isset($v_result_list[$key])) {
1804
            // ----- Error log
1805
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1806
1807
            // ----- Return
1808
            return PclZip::errorCode();
1809
          }
1810
        }
1811
      }
1812
    }
1813
1814
    // ----- Look for default values
1815
    if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1816
1817
    }
1818
1819
    // ----- Return
1820
    return $v_result;
1821
  }
1822
  // --------------------------------------------------------------------------------
1823
1824
  // --------------------------------------------------------------------------------
1825
  // Function : privOptionDefaultThreshold()
1826
  // Description :
1827
  // Parameters :
1828
  // Return Values :
1829
  // --------------------------------------------------------------------------------
1830
  function privOptionDefaultThreshold(&$p_options)
1831
  {
1832
    $v_result=1;
1833
1834
    if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1835
        || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1836
      return $v_result;
1837
    }
1838
1839
    // ----- Get 'memory_limit' configuration value
1840
    $v_memory_limit = ini_get('memory_limit');
1841
    $v_memory_limit = trim($v_memory_limit);
1842
    $v_memory_limit_int = (int) $v_memory_limit;
1843
    $last = strtolower(substr($v_memory_limit, -1));
1844
1845
    if($last == 'g')
1846
        //$v_memory_limit_int = $v_memory_limit_int*1024*1024*1024;
1847
        $v_memory_limit_int = $v_memory_limit_int*1073741824;
1848
    if($last == 'm')
1849
        //$v_memory_limit_int = $v_memory_limit_int*1024*1024;
1850
        $v_memory_limit_int = $v_memory_limit_int*1048576;
1851
    if($last == 'k')
1852
        $v_memory_limit_int = $v_memory_limit_int*1024;
1853
1854
    $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit_int*PCLZIP_TEMPORARY_FILE_RATIO);
1855
1856
1857
    // ----- Sanity check : No threshold if value lower than 1M
1858
    if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1859
      unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1860
    }
1861
1862
    // ----- Return
1863
    return $v_result;
1864
  }
1865
  // --------------------------------------------------------------------------------
1866
1867
  // --------------------------------------------------------------------------------
1868
  // Function : privFileDescrParseAtt()
1869
  // Description :
1870
  // Parameters :
1871
  // Return Values :
1872
  //   1 on success.
1873
  //   0 on failure.
1874
  // --------------------------------------------------------------------------------
1875
  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.

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

Loading history...
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1876
  {
1877
    $v_result=1;
1878
1879
    // ----- For each file in the list check the attributes
1880
    foreach ($p_file_list as $v_key => $v_value) {
1881
1882
      // ----- Check if the option is supported
1883 View Code Duplication
      if (!isset($v_requested_options[$v_key])) {
1884
        // ----- Error log
1885
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1886
1887
        // ----- Return
1888
        return PclZip::errorCode();
1889
      }
1890
1891
      // ----- Look for attribute
1892
      switch ($v_key) {
1893 View Code Duplication
        case PCLZIP_ATT_FILE_NAME :
1894
          if (!is_string($v_value)) {
1895
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1896
            return PclZip::errorCode();
1897
          }
1898
1899
          $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1900
1901
          if ($p_filedescr['filename'] == '') {
1902
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1903
            return PclZip::errorCode();
1904
          }
1905
1906
        break;
1907
1908 View Code Duplication
        case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1909
          if (!is_string($v_value)) {
1910
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1911
            return PclZip::errorCode();
1912
          }
1913
1914
          $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1915
1916
          if ($p_filedescr['new_short_name'] == '') {
1917
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1918
            return PclZip::errorCode();
1919
          }
1920
        break;
1921
1922 View Code Duplication
        case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1923
          if (!is_string($v_value)) {
1924
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1925
            return PclZip::errorCode();
1926
          }
1927
1928
          $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1929
1930
          if ($p_filedescr['new_full_name'] == '') {
1931
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1932
            return PclZip::errorCode();
1933
          }
1934
        break;
1935
1936
        // ----- Look for options that takes a string
1937 View Code Duplication
        case PCLZIP_ATT_FILE_COMMENT :
1938
          if (!is_string($v_value)) {
1939
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1940
            return PclZip::errorCode();
1941
          }
1942
1943
          $p_filedescr['comment'] = $v_value;
1944
        break;
1945
1946 View Code Duplication
        case PCLZIP_ATT_FILE_MTIME :
1947
          if (!is_integer($v_value)) {
1948
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1949
            return PclZip::errorCode();
1950
          }
1951
1952
          $p_filedescr['mtime'] = $v_value;
1953
        break;
1954
1955
        case PCLZIP_ATT_FILE_CONTENT :
1956
          $p_filedescr['content'] = $v_value;
1957
        break;
1958
1959
        default :
1960
          // ----- Error log
1961
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1962
		                           "Unknown parameter '".$v_key."'");
1963
1964
          // ----- Return
1965
          return PclZip::errorCode();
1966
      }
1967
1968
      // ----- Look for mandatory options
1969 View Code Duplication
      if ($v_requested_options !== false) {
1970
        for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1971
          // ----- Look for mandatory option
1972
          if ($v_requested_options[$key] == 'mandatory') {
1973
            // ----- Look if present
1974
            if (!isset($p_file_list[$key])) {
1975
              PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1976
              return PclZip::errorCode();
1977
            }
1978
          }
1979
        }
1980
      }
1981
1982
    // end foreach
1983
    }
1984
1985
    // ----- Return
1986
    return $v_result;
1987
  }
1988
  // --------------------------------------------------------------------------------
1989
1990
  // --------------------------------------------------------------------------------
1991
  // Function : privFileDescrExpand()
1992
  // Description :
1993
  //   This method look for each item of the list to see if its a file, a folder
1994
  //   or a string to be added as file. For any other type of files (link, other)
1995
  //   just ignore the item.
1996
  //   Then prepare the information that will be stored for that file.
1997
  //   When its a folder, expand the folder with all the files that are in that
1998
  //   folder (recursively).
1999
  // Parameters :
2000
  // Return Values :
2001
  //   1 on success.
2002
  //   0 on failure.
2003
  // --------------------------------------------------------------------------------
2004
  function privFileDescrExpand(&$p_filedescr_list, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2005
  {
2006
    $v_result=1;
2007
2008
    // ----- Create a result list
2009
    $v_result_list = array();
2010
2011
    // ----- Look each entry
2012
    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...
2013
2014
      // ----- Get filedescr
2015
      $v_descr = $p_filedescr_list[$i];
2016
2017
      // ----- Reduce the filename
2018
      $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
2019
      $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
2020
2021
      // ----- Look for real file or folder
2022
      if (file_exists($v_descr['filename'])) {
2023
        if (@is_file($v_descr['filename'])) {
2024
          $v_descr['type'] = 'file';
2025
        }
2026
        else if (@is_dir($v_descr['filename'])) {
2027
          $v_descr['type'] = 'folder';
2028
        }
2029
        else if (@is_link($v_descr['filename'])) {
2030
          // skip
2031
          continue;
2032
        }
2033
        else {
2034
          // skip
2035
          continue;
2036
        }
2037
      }
2038
2039
      // ----- Look for string added as file
2040
      else if (isset($v_descr['content'])) {
2041
        $v_descr['type'] = 'virtual_file';
2042
      }
2043
2044
      // ----- Missing file
2045
      else {
2046
        // ----- Error log
2047
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
2048
2049
        // ----- Return
2050
        return PclZip::errorCode();
2051
      }
2052
2053
      // ----- Calculate the stored filename
2054
      $this->privCalculateStoredFilename($v_descr, $p_options);
2055
2056
      // ----- Add the descriptor in result list
2057
      $v_result_list[sizeof($v_result_list)] = $v_descr;
2058
2059
      // ----- Look for folder
2060
      if ($v_descr['type'] == 'folder') {
2061
        // ----- List of items in folder
2062
        $v_dirlist_descr = array();
2063
        $v_dirlist_nb = 0;
2064
        if ($v_folder_handler = @opendir($v_descr['filename'])) {
2065
          while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2066
2067
            // ----- Skip '.' and '..'
2068
            if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2069
                continue;
2070
            }
2071
2072
            // ----- Compose the full filename
2073
            $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2074
2075
            // ----- Look for different stored filename
2076
            // Because the name of the folder was changed, the name of the
2077
            // files/sub-folders also change
2078
            if (($v_descr['stored_filename'] != $v_descr['filename'])
2079
                 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2080
              if ($v_descr['stored_filename'] != '') {
2081
                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2082
              }
2083
              else {
2084
                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2085
              }
2086
            }
2087
2088
            $v_dirlist_nb++;
2089
          }
2090
2091
          @closedir($v_folder_handler);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2092
        }
2093
        else {
2094
          // TBC : unable to open folder in read mode
2095
        }
2096
2097
        // ----- Expand each element of the list
2098
        if ($v_dirlist_nb != 0) {
2099
          // ----- Expand
2100
          if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2101
            return $v_result;
2102
          }
2103
2104
          // ----- Concat the resulting list
2105
          $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2106
        }
2107
        else {
2108
        }
2109
2110
        // ----- Free local array
2111
        unset($v_dirlist_descr);
2112
      }
2113
    }
2114
2115
    // ----- Get the result list
2116
    $p_filedescr_list = $v_result_list;
2117
2118
    // ----- Return
2119
    return $v_result;
2120
  }
2121
  // --------------------------------------------------------------------------------
2122
2123
  // --------------------------------------------------------------------------------
2124
  // Function : privCreate()
2125
  // Description :
2126
  // Parameters :
2127
  // Return Values :
2128
  // --------------------------------------------------------------------------------
2129
  function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2130
  {
2131
    $v_result=1;
2132
    $v_list_detail = array();
2133
2134
    // ----- Magic quotes trick
2135
    $this->privDisableMagicQuotes();
2136
2137
    // ----- Open the file in write mode
2138
    if (($v_result = $this->privOpenFd('wb')) != 1)
2139
    {
2140
      // ----- Return
2141
      return $v_result;
2142
    }
2143
2144
    // ----- Add the list of files
2145
    $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2146
2147
    // ----- Close
2148
    $this->privCloseFd();
2149
2150
    // ----- Magic quotes trick
2151
    $this->privSwapBackMagicQuotes();
2152
2153
    // ----- Return
2154
    return $v_result;
2155
  }
2156
  // --------------------------------------------------------------------------------
2157
2158
  // --------------------------------------------------------------------------------
2159
  // Function : privAdd()
2160
  // Description :
2161
  // Parameters :
2162
  // Return Values :
2163
  // --------------------------------------------------------------------------------
2164
  function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2165
  {
2166
    $v_result=1;
2167
    $v_list_detail = array();
2168
2169
    // ----- Look if the archive exists or is empty
2170
    if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2171
    {
2172
2173
      // ----- Do a create
2174
      $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2175
2176
      // ----- Return
2177
      return $v_result;
2178
    }
2179
    // ----- Magic quotes trick
2180
    $this->privDisableMagicQuotes();
2181
2182
    // ----- Open the zip file
2183
    if (($v_result=$this->privOpenFd('rb')) != 1)
2184
    {
2185
      // ----- Magic quotes trick
2186
      $this->privSwapBackMagicQuotes();
2187
2188
      // ----- Return
2189
      return $v_result;
2190
    }
2191
2192
    // ----- Read the central directory informations
2193
    $v_central_dir = array();
2194
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2195
    {
2196
      $this->privCloseFd();
2197
      $this->privSwapBackMagicQuotes();
2198
      return $v_result;
2199
    }
2200
2201
    // ----- Go to beginning of File
2202
    @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2203
2204
    // ----- Creates a temporay file
2205
    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2206
2207
    // ----- Open the temporary file in write mode
2208
    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2209
    {
2210
      $this->privCloseFd();
2211
      $this->privSwapBackMagicQuotes();
2212
2213
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2214
2215
      // ----- Return
2216
      return PclZip::errorCode();
2217
    }
2218
2219
    // ----- Copy the files from the archive to the temporary file
2220
    // TBC : Here I should better append the file and go back to erase the central dir
2221
    $v_size = $v_central_dir['offset'];
2222
    while ($v_size != 0)
2223
    {
2224
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2225
      $v_buffer = fread($this->zip_fd, $v_read_size);
2226
      @fwrite($v_zip_temp_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 here. This can introduce security issues, and is generally not recommended.

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...
2227
      $v_size -= $v_read_size;
2228
    }
2229
2230
    // ----- Swap the file descriptor
2231
    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2232
    // the following methods on the temporary fil and not the real archive
2233
    $v_swap = $this->zip_fd;
2234
    $this->zip_fd = $v_zip_temp_fd;
2235
    $v_zip_temp_fd = $v_swap;
2236
2237
    // ----- Add the files
2238
    $v_header_list = array();
2239 View Code Duplication
    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2240
    {
2241
      fclose($v_zip_temp_fd);
2242
      $this->privCloseFd();
2243
      @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2244
      $this->privSwapBackMagicQuotes();
2245
2246
      // ----- Return
2247
      return $v_result;
2248
    }
2249
2250
    // ----- Store the offset of the central dir
2251
    $v_offset = @ftell($this->zip_fd);
2252
2253
    // ----- Copy the block of file headers from the old archive
2254
    $v_size = $v_central_dir['size'];
2255 View Code Duplication
    while ($v_size != 0)
2256
    {
2257
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2258
      $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2259
      @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 here. This can introduce security issues, and is generally not recommended.

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...
2260
      $v_size -= $v_read_size;
2261
    }
2262
2263
    // ----- Create the Central Dir files header
2264
    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...
2265
    {
2266
      // ----- Create the file header
2267
      if ($v_header_list[$i]['status'] == 'ok') {
2268 View Code Duplication
        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2269
          fclose($v_zip_temp_fd);
2270
          $this->privCloseFd();
2271
          @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2272
          $this->privSwapBackMagicQuotes();
2273
2274
          // ----- Return
2275
          return $v_result;
2276
        }
2277
        $v_count++;
2278
      }
2279
2280
      // ----- Transform the header to a 'usable' info
2281
      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2282
    }
2283
2284
    // ----- Zip file comment
2285
    $v_comment = $v_central_dir['comment'];
2286
    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2287
      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2288
    }
2289
    if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2290
      $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2291
    }
2292
    if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2293
      $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2294
    }
2295
2296
    // ----- Calculate the size of the central header
2297
    $v_size = @ftell($this->zip_fd)-$v_offset;
2298
2299
    // ----- Create the central dir footer
2300
    if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2301
    {
2302
      // ----- Reset the file list
2303
      unset($v_header_list);
2304
      $this->privSwapBackMagicQuotes();
2305
2306
      // ----- Return
2307
      return $v_result;
2308
    }
2309
2310
    // ----- Swap back the file descriptor
2311
    $v_swap = $this->zip_fd;
2312
    $this->zip_fd = $v_zip_temp_fd;
2313
    $v_zip_temp_fd = $v_swap;
2314
2315
    // ----- Close
2316
    $this->privCloseFd();
2317
2318
    // ----- Close the temporary file
2319
    @fclose($v_zip_temp_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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
    // ----- Magic quotes trick
2322
    $this->privSwapBackMagicQuotes();
2323
2324
    // ----- Delete the zip file
2325
    // TBC : I should test the result ...
2326
    @unlink($this->zipname);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2327
2328
    // ----- Rename the temporary file
2329
    // TBC : I should test the result ...
2330
    //@rename($v_zip_temp_name, $this->zipname);
2331
    PclZipUtilRename($v_zip_temp_name, $this->zipname);
2332
2333
    // ----- Return
2334
    return $v_result;
2335
  }
2336
  // --------------------------------------------------------------------------------
2337
2338
  // --------------------------------------------------------------------------------
2339
  // Function : privOpenFd()
2340
  // Description :
2341
  // Parameters :
2342
  // --------------------------------------------------------------------------------
2343
  function privOpenFd($p_mode)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2344
  {
2345
    $v_result=1;
2346
2347
    // ----- Look if already open
2348
    if ($this->zip_fd != 0)
2349
    {
2350
      // ----- Error log
2351
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2352
2353
      // ----- Return
2354
      return PclZip::errorCode();
2355
    }
2356
2357
    // ----- Open the zip file
2358
    if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2359
    {
2360
      // ----- Error log
2361
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2362
2363
      // ----- Return
2364
      return PclZip::errorCode();
2365
    }
2366
2367
    // ----- Return
2368
    return $v_result;
2369
  }
2370
  // --------------------------------------------------------------------------------
2371
2372
  // --------------------------------------------------------------------------------
2373
  // Function : privCloseFd()
2374
  // Description :
2375
  // Parameters :
2376
  // --------------------------------------------------------------------------------
2377
  function privCloseFd()
2378
  {
2379
    $v_result=1;
2380
2381
    if ($this->zip_fd != 0)
2382
      @fclose($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2383
    $this->zip_fd = 0;
2384
2385
    // ----- Return
2386
    return $v_result;
2387
  }
2388
  // --------------------------------------------------------------------------------
2389
2390
  // --------------------------------------------------------------------------------
2391
  // Function : privAddList()
2392
  // Description :
2393
  //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2394
  //   different from the real path of the file. This is usefull if you want to have PclTar
2395
  //   running in any directory, and memorize relative path from an other directory.
2396
  // Parameters :
2397
  //   $p_list : An array containing the file or directory names to add in the tar
2398
  //   $p_result_list : list of added files with their properties (specially the status field)
2399
  //   $p_add_dir : Path to add in the filename path archived
2400
  //   $p_remove_dir : Path to remove in the filename path archived
2401
  // Return Values :
2402
  // --------------------------------------------------------------------------------
2403
//  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2404
  function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2405
  {
2406
    $v_result=1;
2407
2408
    // ----- Add the files
2409
    $v_header_list = array();
2410
    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2411
    {
2412
      // ----- Return
2413
      return $v_result;
2414
    }
2415
2416
    // ----- Store the offset of the central dir
2417
    $v_offset = @ftell($this->zip_fd);
2418
2419
    // ----- Create the Central Dir files header
2420
    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...
2421
    {
2422
      // ----- Create the file header
2423
      if ($v_header_list[$i]['status'] == 'ok') {
2424
        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2425
          // ----- Return
2426
          return $v_result;
2427
        }
2428
        $v_count++;
2429
      }
2430
2431
      // ----- Transform the header to a 'usable' info
2432
      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2433
    }
2434
2435
    // ----- Zip file comment
2436
    $v_comment = '';
2437
    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2438
      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2439
    }
2440
2441
    // ----- Calculate the size of the central header
2442
    $v_size = @ftell($this->zip_fd)-$v_offset;
2443
2444
    // ----- Create the central dir footer
2445
    if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2446
    {
2447
      // ----- Reset the file list
2448
      unset($v_header_list);
2449
2450
      // ----- Return
2451
      return $v_result;
2452
    }
2453
2454
    // ----- Return
2455
    return $v_result;
2456
  }
2457
  // --------------------------------------------------------------------------------
2458
2459
  // --------------------------------------------------------------------------------
2460
  // Function : privAddFileList()
2461
  // Description :
2462
  // Parameters :
2463
  //   $p_filedescr_list : An array containing the file description
2464
  //                      or directory names to add in the zip
2465
  //   $p_result_list : list of added files with their properties (specially the status field)
2466
  // Return Values :
2467
  // --------------------------------------------------------------------------------
2468
  function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2469
  {
2470
    $v_result=1;
2471
    $v_header = array();
2472
2473
    // ----- Recuperate the current number of elt in list
2474
    $v_nb = sizeof($p_result_list);
2475
2476
    // ----- Loop on the files
2477
    for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2478
      // ----- Format the filename
2479
      $p_filedescr_list[$j]['filename']
2480
      = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2481
2482
2483
      // ----- Skip empty file names
2484
      // TBC : Can this be possible ? not checked in DescrParseAtt ?
2485
      if ($p_filedescr_list[$j]['filename'] == "") {
2486
        continue;
2487
      }
2488
2489
      // ----- Check the filename
2490
      if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')
2491
          && (!file_exists($p_filedescr_list[$j]['filename']))) {
2492
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
2493
        return PclZip::errorCode();
2494
      }
2495
2496
      // ----- Look if it is a file or a dir with no all path remove option
2497
      // or a dir with all its path removed
2498
//      if (   (is_file($p_filedescr_list[$j]['filename']))
2499
//          || (   is_dir($p_filedescr_list[$j]['filename'])
2500
      if (   ($p_filedescr_list[$j]['type'] == 'file')
2501
          || ($p_filedescr_list[$j]['type'] == 'virtual_file')
2502
          || (   ($p_filedescr_list[$j]['type'] == 'folder')
2503
              && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2504
                  || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
2505
          ) {
2506
2507
        // ----- Add the file
2508
        $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2509
                                       $p_options);
2510
        if ($v_result != 1) {
2511
          return $v_result;
2512
        }
2513
2514
        // ----- Store the file infos
2515
        $p_result_list[$v_nb++] = $v_header;
2516
      }
2517
    }
2518
2519
    // ----- Return
2520
    return $v_result;
2521
  }
2522
  // --------------------------------------------------------------------------------
2523
2524
  // --------------------------------------------------------------------------------
2525
  // Function : privAddFile()
2526
  // Description :
2527
  // Parameters :
2528
  // Return Values :
2529
  // --------------------------------------------------------------------------------
2530
  function privAddFile($p_filedescr, &$p_header, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2531
  {
2532
    $v_result=1;
2533
2534
    // ----- Working variable
2535
    $p_filename = $p_filedescr['filename'];
2536
2537
    // TBC : Already done in the fileAtt check ... ?
2538
    if ($p_filename == "") {
2539
      // ----- Error log
2540
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2541
2542
      // ----- Return
2543
      return PclZip::errorCode();
2544
    }
2545
2546
    // ----- Look for a stored different filename
2547
    /* TBC : Removed
2548
    if (isset($p_filedescr['stored_filename'])) {
2549
      $v_stored_filename = $p_filedescr['stored_filename'];
2550
    }
2551
    else {
2552
      $v_stored_filename = $p_filedescr['stored_filename'];
2553
    }
2554
    */
2555
2556
    // ----- Set the file properties
2557
    clearstatcache();
2558
    $p_header['version'] = 20;
2559
    $p_header['version_extracted'] = 10;
2560
    $p_header['flag'] = 0;
2561
    $p_header['compression'] = 0;
2562
    $p_header['crc'] = 0;
2563
    $p_header['compressed_size'] = 0;
2564
    $p_header['filename_len'] = strlen($p_filename);
2565
    $p_header['extra_len'] = 0;
2566
    $p_header['disk'] = 0;
2567
    $p_header['internal'] = 0;
2568
    $p_header['offset'] = 0;
2569
    $p_header['filename'] = $p_filename;
2570
// TBC : Removed    $p_header['stored_filename'] = $v_stored_filename;
2571
    $p_header['stored_filename'] = $p_filedescr['stored_filename'];
2572
    $p_header['extra'] = '';
2573
    $p_header['status'] = 'ok';
2574
    $p_header['index'] = -1;
2575
2576
    // ----- Look for regular file
2577
    if ($p_filedescr['type']=='file') {
2578
      $p_header['external'] = 0x00000000;
2579
      $p_header['size'] = filesize($p_filename);
2580
    }
2581
2582
    // ----- Look for regular folder
2583
    else if ($p_filedescr['type']=='folder') {
2584
      $p_header['external'] = 0x00000010;
2585
      $p_header['mtime'] = filemtime($p_filename);
2586
      $p_header['size'] = filesize($p_filename);
2587
    }
2588
2589
    // ----- Look for virtual file
2590
    else if ($p_filedescr['type'] == 'virtual_file') {
2591
      $p_header['external'] = 0x00000000;
2592
      $p_header['size'] = strlen($p_filedescr['content']);
2593
    }
2594
2595
2596
    // ----- Look for filetime
2597
    if (isset($p_filedescr['mtime'])) {
2598
      $p_header['mtime'] = $p_filedescr['mtime'];
2599
    }
2600
    else if ($p_filedescr['type'] == 'virtual_file') {
2601
      $p_header['mtime'] = time();
2602
    }
2603
    else {
2604
      $p_header['mtime'] = filemtime($p_filename);
2605
    }
2606
2607
    // ------ Look for file comment
2608
    if (isset($p_filedescr['comment'])) {
2609
      $p_header['comment_len'] = strlen($p_filedescr['comment']);
2610
      $p_header['comment'] = $p_filedescr['comment'];
2611
    }
2612
    else {
2613
      $p_header['comment_len'] = 0;
2614
      $p_header['comment'] = '';
2615
    }
2616
2617
    // ----- Look for pre-add callback
2618
    if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2619
2620
      // ----- Generate a local information
2621
      $v_local_header = array();
2622
      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2623
2624
      // ----- Call the callback
2625
      // Here I do not use call_user_func() because I need to send a reference to the
2626
      // header.
2627
      $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2628
      if ($v_result == 0) {
2629
        // ----- Change the file status
2630
        $p_header['status'] = "skipped";
2631
        $v_result = 1;
2632
      }
2633
2634
      // ----- Update the informations
2635
      // Only some fields can be modified
2636
      if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2637
        $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2638
      }
2639
    }
2640
2641
    // ----- Look for empty stored filename
2642
    if ($p_header['stored_filename'] == "") {
2643
      $p_header['status'] = "filtered";
2644
    }
2645
2646
    // ----- Check the path length
2647
    if (strlen($p_header['stored_filename']) > 0xFF) {
2648
      $p_header['status'] = 'filename_too_long';
2649
    }
2650
2651
    // ----- Look if no error, or file not skipped
2652
    if ($p_header['status'] == 'ok') {
2653
2654
      // ----- Look for a file
2655
      if ($p_filedescr['type'] == 'file') {
2656
        // ----- Look for using temporary file to zip
2657
        if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
2658
            && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2659
                || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2660
                    && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
2661
          $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2662
          if ($v_result < PCLZIP_ERR_NO_ERROR) {
2663
            return $v_result;
2664
          }
2665
        }
2666
2667
        // ----- Use "in memory" zip algo
2668
        else {
2669
2670
        // ----- Open the source file
2671 View Code Duplication
        if (($v_file = @fopen($p_filename, "rb")) == 0) {
2672
          PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2673
          return PclZip::errorCode();
2674
        }
2675
2676
        // ----- Read the file content
2677
        $v_content = @fread($v_file, $p_header['size']);
2678
2679
        // ----- Close the file
2680
        @fclose($v_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2681
2682
        // ----- Calculate the CRC
2683
        $p_header['crc'] = @crc32($v_content);
2684
2685
        // ----- Look for no compression
2686 View Code Duplication
        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2687
          // ----- Set header parameters
2688
          $p_header['compressed_size'] = $p_header['size'];
2689
          $p_header['compression'] = 0;
2690
        }
2691
2692
        // ----- Look for normal compression
2693
        else {
2694
          // ----- Compress the content
2695
          $v_content = @gzdeflate($v_content);
2696
2697
          // ----- Set header parameters
2698
          $p_header['compressed_size'] = strlen($v_content);
2699
          $p_header['compression'] = 8;
2700
        }
2701
2702
        // ----- Call the header generation
2703
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2704
          @fclose($v_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2705
          return $v_result;
2706
        }
2707
2708
        // ----- Write the compressed (or not) content
2709
        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2710
2711
        }
2712
2713
      }
2714
2715
      // ----- Look for a virtual file (a file from string)
2716
      else if ($p_filedescr['type'] == 'virtual_file') {
2717
2718
        $v_content = $p_filedescr['content'];
2719
2720
        // ----- Calculate the CRC
2721
        $p_header['crc'] = @crc32($v_content);
2722
2723
        // ----- Look for no compression
2724 View Code Duplication
        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2725
          // ----- Set header parameters
2726
          $p_header['compressed_size'] = $p_header['size'];
2727
          $p_header['compression'] = 0;
2728
        }
2729
2730
        // ----- Look for normal compression
2731
        else {
2732
          // ----- Compress the content
2733
          $v_content = @gzdeflate($v_content);
2734
2735
          // ----- Set header parameters
2736
          $p_header['compressed_size'] = strlen($v_content);
2737
          $p_header['compression'] = 8;
2738
        }
2739
2740
        // ----- Call the header generation
2741
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2742
          @fclose($v_file);
0 ignored issues
show
Bug introduced by
The variable $v_file seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2743
          return $v_result;
2744
        }
2745
2746
        // ----- Write the compressed (or not) content
2747
        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2748
      }
2749
2750
      // ----- Look for a directory
2751
      else if ($p_filedescr['type'] == 'folder') {
2752
        // ----- Look for directory last '/'
2753
        if (@substr($p_header['stored_filename'], -1) != '/') {
2754
          $p_header['stored_filename'] .= '/';
2755
        }
2756
2757
        // ----- Set the file properties
2758
        $p_header['size'] = 0;
2759
        //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
2760
        $p_header['external'] = 0x00000010;   // Value for a folder : to be checked
2761
2762
        // ----- Call the header generation
2763
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2764
        {
2765
          return $v_result;
2766
        }
2767
      }
2768
    }
2769
2770
    // ----- Look for post-add callback
2771
    if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2772
2773
      // ----- Generate a local information
2774
      $v_local_header = array();
2775
      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2776
2777
      // ----- Call the callback
2778
      // Here I do not use call_user_func() because I need to send a reference to the
2779
      // header.
2780
      $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2781
      if ($v_result == 0) {
2782
        // ----- Ignored
2783
        $v_result = 1;
2784
      }
2785
2786
      // ----- Update the informations
2787
      // Nothing can be modified
2788
    }
2789
2790
    // ----- Return
2791
    return $v_result;
2792
  }
2793
  // --------------------------------------------------------------------------------
2794
2795
  // --------------------------------------------------------------------------------
2796
  // Function : privAddFileUsingTempFile()
2797
  // Description :
2798
  // Parameters :
2799
  // Return Values :
2800
  // --------------------------------------------------------------------------------
2801
  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.

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

Loading history...
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2802
  {
2803
    $v_result=PCLZIP_ERR_NO_ERROR;
2804
2805
    // ----- Working variable
2806
    $p_filename = $p_filedescr['filename'];
2807
2808
2809
    // ----- Open the source file
2810 View Code Duplication
    if (($v_file = @fopen($p_filename, "rb")) == 0) {
2811
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2812
      return PclZip::errorCode();
2813
    }
2814
2815
    // ----- Creates a compressed temporary file
2816
    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2817 View Code Duplication
    if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2818
      fclose($v_file);
2819
      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2820
      return PclZip::errorCode();
2821
    }
2822
2823
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2824
    $v_size = filesize($p_filename);
2825
    while ($v_size != 0) {
2826
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2827
      $v_buffer = @fread($v_file, $v_read_size);
2828
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2829
      @gzputs($v_file_compressed, $v_buffer, $v_read_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2830
      $v_size -= $v_read_size;
2831
    }
2832
2833
    // ----- Close the file
2834
    @fclose($v_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2835
    @gzclose($v_file_compressed);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2836
2837
    // ----- Check the minimum file size
2838 View Code Duplication
    if (filesize($v_gzip_temp_name) < 18) {
2839
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
2840
      return PclZip::errorCode();
2841
    }
2842
2843
    // ----- Extract the compressed attributes
2844 View Code Duplication
    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2845
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2846
      return PclZip::errorCode();
2847
    }
2848
2849
    // ----- Read the gzip file header
2850
    $v_binary_data = @fread($v_file_compressed, 10);
2851
    $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
2852
2853
    // ----- Check some parameters
2854
    $v_data_header['os'] = bin2hex($v_data_header['os']);
2855
2856
    // ----- Read the gzip file footer
2857
    @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 here. This can introduce security issues, and is generally not recommended.

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...
2858
    $v_binary_data = @fread($v_file_compressed, 8);
2859
    $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2860
2861
    // ----- Set the attributes
2862
    $p_header['compression'] = ord($v_data_header['cm']);
2863
    //$p_header['mtime'] = $v_data_header['mtime'];
2864
    $p_header['crc'] = $v_data_footer['crc'];
2865
    $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
2866
2867
    // ----- Close the file
2868
    @fclose($v_file_compressed);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2869
2870
    // ----- Call the header generation
2871
    if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2872
      return $v_result;
2873
    }
2874
2875
    // ----- Add the compressed data
2876 View Code Duplication
    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
2877
    {
2878
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2879
      return PclZip::errorCode();
2880
    }
2881
2882
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2883
    fseek($v_file_compressed, 10);
2884
    $v_size = $p_header['compressed_size'];
2885 View Code Duplication
    while ($v_size != 0)
2886
    {
2887
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2888
      $v_buffer = @fread($v_file_compressed, $v_read_size);
2889
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2890
      @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 here. This can introduce security issues, and is generally not recommended.

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...
2891
      $v_size -= $v_read_size;
2892
    }
2893
2894
    // ----- Close the file
2895
    @fclose($v_file_compressed);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2896
2897
    // ----- Unlink the temporary file
2898
    @unlink($v_gzip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
2899
2900
    // ----- Return
2901
    return $v_result;
2902
  }
2903
  // --------------------------------------------------------------------------------
2904
2905
  // --------------------------------------------------------------------------------
2906
  // Function : privCalculateStoredFilename()
2907
  // Description :
2908
  //   Based on file descriptor properties and global options, this method
2909
  //   calculate the filename that will be stored in the archive.
2910
  // Parameters :
2911
  // Return Values :
2912
  // --------------------------------------------------------------------------------
2913
  function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2914
  {
2915
    $v_result=1;
2916
2917
    // ----- Working variables
2918
    $p_filename = $p_filedescr['filename'];
2919
    if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2920
      $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2921
    }
2922
    else {
2923
      $p_add_dir = '';
2924
    }
2925
    if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2926
      $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2927
    }
2928
    else {
2929
      $p_remove_dir = '';
2930
    }
2931
    if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2932
      $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2933
    }
2934
    else {
2935
      $p_remove_all_dir = 0;
2936
    }
2937
2938
2939
    // ----- Look for full name change
2940
    if (isset($p_filedescr['new_full_name'])) {
2941
      // ----- Remove drive letter if any
2942
      $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2943
    }
2944
2945
    // ----- Look for path and/or short name change
2946
    else {
2947
2948
      // ----- Look for short name change
2949
      // Its when we cahnge just the filename but not the path
2950
      if (isset($p_filedescr['new_short_name'])) {
2951
        $v_path_info = pathinfo($p_filename);
2952
        $v_dir = '';
2953
        if ($v_path_info['dirname'] != '') {
2954
          $v_dir = $v_path_info['dirname'].'/';
2955
        }
2956
        $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2957
      }
2958
      else {
2959
        // ----- Calculate the stored filename
2960
        $v_stored_filename = $p_filename;
2961
      }
2962
2963
      // ----- Look for all path to remove
2964
      if ($p_remove_all_dir) {
2965
        $v_stored_filename = basename($p_filename);
2966
      }
2967
      // ----- Look for partial path remove
2968
      else if ($p_remove_dir != "") {
2969
        if (substr($p_remove_dir, -1) != '/')
2970
          $p_remove_dir .= "/";
2971
2972
        if (   (substr($p_filename, 0, 2) == "./")
2973
            || (substr($p_remove_dir, 0, 2) == "./")) {
2974
2975 View Code Duplication
          if (   (substr($p_filename, 0, 2) == "./")
2976
              && (substr($p_remove_dir, 0, 2) != "./")) {
2977
            $p_remove_dir = "./".$p_remove_dir;
2978
          }
2979 View Code Duplication
          if (   (substr($p_filename, 0, 2) != "./")
2980
              && (substr($p_remove_dir, 0, 2) == "./")) {
2981
            $p_remove_dir = substr($p_remove_dir, 2);
2982
          }
2983
        }
2984
2985
        $v_compare = PclZipUtilPathInclusion($p_remove_dir,
2986
                                             $v_stored_filename);
2987
        if ($v_compare > 0) {
2988
          if ($v_compare == 2) {
2989
            $v_stored_filename = "";
2990
          }
2991
          else {
2992
            $v_stored_filename = substr($v_stored_filename,
2993
                                        strlen($p_remove_dir));
2994
          }
2995
        }
2996
      }
2997
2998
      // ----- Remove drive letter if any
2999
      $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
3000
3001
      // ----- Look for path to add
3002
      if ($p_add_dir != "") {
3003
        if (substr($p_add_dir, -1) == "/")
3004
          $v_stored_filename = $p_add_dir.$v_stored_filename;
3005
        else
3006
          $v_stored_filename = $p_add_dir."/".$v_stored_filename;
3007
      }
3008
    }
3009
3010
    // ----- Filename (reduce the path of stored name)
3011
    $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
3012
    $p_filedescr['stored_filename'] = $v_stored_filename;
3013
3014
    // ----- Return
3015
    return $v_result;
3016
  }
3017
  // --------------------------------------------------------------------------------
3018
3019
  // --------------------------------------------------------------------------------
3020
  // Function : privWriteFileHeader()
3021
  // Description :
3022
  // Parameters :
3023
  // Return Values :
3024
  // --------------------------------------------------------------------------------
3025
  function privWriteFileHeader(&$p_header)
3026
  {
3027
    $v_result=1;
3028
3029
    // ----- Store the offset position of the file
3030
    $p_header['offset'] = ftell($this->zip_fd);
3031
3032
    // ----- Transform UNIX mtime to DOS format mdate/mtime
3033
    $v_date = getdate($p_header['mtime']);
3034
    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3035
    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3036
3037
    // ----- Packed data
3038
    $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
3039
	                      $p_header['version_extracted'], $p_header['flag'],
3040
                          $p_header['compression'], $v_mtime, $v_mdate,
3041
                          $p_header['crc'], $p_header['compressed_size'],
3042
						  $p_header['size'],
3043
                          strlen($p_header['stored_filename']),
3044
						  $p_header['extra_len']);
3045
3046
    // ----- Write the first 148 bytes of the header in the archive
3047
    fputs($this->zip_fd, $v_binary_data, 30);
3048
3049
    // ----- Write the variable fields
3050 View Code Duplication
    if (strlen($p_header['stored_filename']) != 0)
3051
    {
3052
      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3053
    }
3054 View Code Duplication
    if ($p_header['extra_len'] != 0)
3055
    {
3056
      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3057
    }
3058
3059
    // ----- Return
3060
    return $v_result;
3061
  }
3062
  // --------------------------------------------------------------------------------
3063
3064
  // --------------------------------------------------------------------------------
3065
  // Function : privWriteCentralFileHeader()
3066
  // Description :
3067
  // Parameters :
3068
  // Return Values :
3069
  // --------------------------------------------------------------------------------
3070
  function privWriteCentralFileHeader(&$p_header)
3071
  {
3072
    $v_result=1;
3073
3074
    // TBC
3075
    //for(reset($p_header); $key = key($p_header); next($p_header)) {
3076
    //}
3077
3078
    // ----- Transform UNIX mtime to DOS format mdate/mtime
3079
    $v_date = getdate($p_header['mtime']);
3080
    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3081
    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3082
3083
3084
    // ----- Packed data
3085
    $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
3086
	                      $p_header['version'], $p_header['version_extracted'],
3087
                          $p_header['flag'], $p_header['compression'],
3088
						  $v_mtime, $v_mdate, $p_header['crc'],
3089
                          $p_header['compressed_size'], $p_header['size'],
3090
                          strlen($p_header['stored_filename']),
3091
						  $p_header['extra_len'], $p_header['comment_len'],
3092
                          $p_header['disk'], $p_header['internal'],
3093
						  $p_header['external'], $p_header['offset']);
3094
3095
    // ----- Write the 42 bytes of the header in the zip file
3096
    fputs($this->zip_fd, $v_binary_data, 46);
3097
3098
    // ----- Write the variable fields
3099 View Code Duplication
    if (strlen($p_header['stored_filename']) != 0)
3100
    {
3101
      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3102
    }
3103 View Code Duplication
    if ($p_header['extra_len'] != 0)
3104
    {
3105
      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3106
    }
3107
    if ($p_header['comment_len'] != 0)
3108
    {
3109
      fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
3110
    }
3111
3112
    // ----- Return
3113
    return $v_result;
3114
  }
3115
  // --------------------------------------------------------------------------------
3116
3117
  // --------------------------------------------------------------------------------
3118
  // Function : privWriteCentralHeader()
3119
  // Description :
3120
  // Parameters :
3121
  // Return Values :
3122
  // --------------------------------------------------------------------------------
3123
  function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3124
  {
3125
    $v_result=1;
3126
3127
    // ----- Packed data
3128
    $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
3129
	                      $p_nb_entries, $p_size,
3130
						  $p_offset, strlen($p_comment));
3131
3132
    // ----- Write the 22 bytes of the header in the zip file
3133
    fputs($this->zip_fd, $v_binary_data, 22);
3134
3135
    // ----- Write the variable fields
3136
    if (strlen($p_comment) != 0)
3137
    {
3138
      fputs($this->zip_fd, $p_comment, strlen($p_comment));
3139
    }
3140
3141
    // ----- Return
3142
    return $v_result;
3143
  }
3144
  // --------------------------------------------------------------------------------
3145
3146
  // --------------------------------------------------------------------------------
3147
  // Function : privList()
3148
  // Description :
3149
  // Parameters :
3150
  // Return Values :
3151
  // --------------------------------------------------------------------------------
3152
  function privList(&$p_list)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
3153
  {
3154
    $v_result=1;
3155
3156
    // ----- Magic quotes trick
3157
    $this->privDisableMagicQuotes();
3158
3159
    // ----- Open the zip file
3160 View Code Duplication
    if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
3161
    {
3162
      // ----- Magic quotes trick
3163
      $this->privSwapBackMagicQuotes();
3164
3165
      // ----- Error log
3166
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
3167
3168
      // ----- Return
3169
      return PclZip::errorCode();
3170
    }
3171
3172
    // ----- Read the central directory informations
3173
    $v_central_dir = array();
3174
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3175
    {
3176
      $this->privSwapBackMagicQuotes();
3177
      return $v_result;
3178
    }
3179
3180
    // ----- Go to beginning of Central Dir
3181
    @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
3182 View Code Duplication
    if (@fseek($this->zip_fd, $v_central_dir['offset']))
3183
    {
3184
      $this->privSwapBackMagicQuotes();
3185
3186
      // ----- Error log
3187
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3188
3189
      // ----- Return
3190
      return PclZip::errorCode();
3191
    }
3192
3193
    // ----- Read each entry
3194
    for ($i=0; $i<$v_central_dir['entries']; $i++)
3195
    {
3196
      // ----- Read the file header
3197
      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3198
      {
3199
        $this->privSwapBackMagicQuotes();
3200
        return $v_result;
3201
      }
3202
      $v_header['index'] = $i;
3203
3204
      // ----- Get the only interesting attributes
3205
      $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3206
      unset($v_header);
3207
    }
3208
3209
    // ----- Close the zip file
3210
    $this->privCloseFd();
3211
3212
    // ----- Magic quotes trick
3213
    $this->privSwapBackMagicQuotes();
3214
3215
    // ----- Return
3216
    return $v_result;
3217
  }
3218
  // --------------------------------------------------------------------------------
3219
3220
  // --------------------------------------------------------------------------------
3221
  // Function : privConvertHeader2FileInfo()
3222
  // Description :
3223
  //   This function takes the file informations from the central directory
3224
  //   entries and extract the interesting parameters that will be given back.
3225
  //   The resulting file infos are set in the array $p_info
3226
  //     $p_info['filename'] : Filename with full path. Given by user (add),
3227
  //                           extracted in the filesystem (extract).
3228
  //     $p_info['stored_filename'] : Stored filename in the archive.
3229
  //     $p_info['size'] = Size of the file.
3230
  //     $p_info['compressed_size'] = Compressed size of the file.
3231
  //     $p_info['mtime'] = Last modification date of the file.
3232
  //     $p_info['comment'] = Comment associated with the file.
3233
  //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3234
  //     $p_info['status'] = status of the action on the file.
3235
  //     $p_info['crc'] = CRC of the file content.
3236
  // Parameters :
3237
  // Return Values :
3238
  // --------------------------------------------------------------------------------
3239
  function privConvertHeader2FileInfo($p_header, &$p_info)
3240
  {
3241
    $v_result=1;
3242
3243
    // ----- Get the interesting attributes
3244
    $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
3245
    $p_info['filename'] = $v_temp_path;
3246
    $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
3247
    $p_info['stored_filename'] = $v_temp_path;
3248
    $p_info['size'] = $p_header['size'];
3249
    $p_info['compressed_size'] = $p_header['compressed_size'];
3250
    $p_info['mtime'] = $p_header['mtime'];
3251
    $p_info['comment'] = $p_header['comment'];
3252
    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3253
    $p_info['index'] = $p_header['index'];
3254
    $p_info['status'] = $p_header['status'];
3255
    $p_info['crc'] = $p_header['crc'];
3256
3257
    // ----- Return
3258
    return $v_result;
3259
  }
3260
  // --------------------------------------------------------------------------------
3261
3262
  // --------------------------------------------------------------------------------
3263
  // Function : privExtractByRule()
3264
  // Description :
3265
  //   Extract a file or directory depending of rules (by index, by name, ...)
3266
  // Parameters :
3267
  //   $p_file_list : An array where will be placed the properties of each
3268
  //                  extracted file
3269
  //   $p_path : Path to add while writing the extracted files
3270
  //   $p_remove_path : Path to remove (from the file memorized path) while writing the
3271
  //                    extracted files. If the path does not match the file path,
3272
  //                    the file is extracted with its memorized path.
3273
  //                    $p_remove_path does not apply to 'list' mode.
3274
  //                    $p_path and $p_remove_path are commulative.
3275
  // Return Values :
3276
  //   1 on success,0 or less on error (see error code list)
3277
  // --------------------------------------------------------------------------------
3278
  function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
3279
  {
3280
    $v_result=1;
3281
3282
    // ----- Magic quotes trick
3283
    $this->privDisableMagicQuotes();
3284
3285
    // ----- Check the path
3286
    if (   ($p_path == "")
3287
	    || (   (substr($p_path, 0, 1) != "/")
3288
		    && (substr($p_path, 0, 3) != "../")
3289
			&& (substr($p_path,1,2)!=":/")))
3290
      $p_path = "./".$p_path;
3291
3292
    // ----- Reduce the path last (and duplicated) '/'
3293
    if (($p_path != "./") && ($p_path != "/"))
3294
    {
3295
      // ----- Look for the path end '/'
3296 View Code Duplication
      while (substr($p_path, -1) == "/")
3297
      {
3298
        $p_path = substr($p_path, 0, strlen($p_path)-1);
3299
      }
3300
    }
3301
3302
    // ----- Look for path to remove format (should end by /)
3303
    if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3304
    {
3305
      $p_remove_path .= '/';
3306
    }
3307
    $p_remove_path_size = strlen($p_remove_path);
3308
3309
    // ----- Open the zip file
3310
    if (($v_result = $this->privOpenFd('rb')) != 1)
3311
    {
3312
      $this->privSwapBackMagicQuotes();
3313
      return $v_result;
3314
    }
3315
3316
    // ----- Read the central directory informations
3317
    $v_central_dir = array();
3318
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3319
    {
3320
      // ----- Close the zip file
3321
      $this->privCloseFd();
3322
      $this->privSwapBackMagicQuotes();
3323
3324
      return $v_result;
3325
    }
3326
3327
    // ----- Start at beginning of Central Dir
3328
    $v_pos_entry = $v_central_dir['offset'];
3329
3330
    // ----- Read each entry
3331
    $j_start = 0;
3332
    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3333
    {
3334
3335
      // ----- Read next Central dir entry
3336
      @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
3337 View Code Duplication
      if (@fseek($this->zip_fd, $v_pos_entry))
3338
      {
3339
        // ----- Close the zip file
3340
        $this->privCloseFd();
3341
        $this->privSwapBackMagicQuotes();
3342
3343
        // ----- Error log
3344
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3345
3346
        // ----- Return
3347
        return PclZip::errorCode();
3348
      }
3349
3350
      // ----- Read the file header
3351
      $v_header = array();
3352
      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3353
      {
3354
        // ----- Close the zip file
3355
        $this->privCloseFd();
3356
        $this->privSwapBackMagicQuotes();
3357
3358
        return $v_result;
3359
      }
3360
3361
      // ----- Store the index
3362
      $v_header['index'] = $i;
3363
3364
      // ----- Store the file position
3365
      $v_pos_entry = ftell($this->zip_fd);
3366
3367
      // ----- Look for the specific extract rules
3368
      $v_extract = false;
3369
3370
      // ----- Look for extract by name rule
3371
      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
3372
          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3373
3374
          // ----- Look if the filename is in the list
3375
          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3376
3377
              // ----- Look for a directory
3378
              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3379
3380
                  // ----- Look if the directory is in the filename path
3381
                  if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3382
                      && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3383
                      $v_extract = true;
3384
                  }
3385
              }
3386
              // ----- Look for a filename
3387
              elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3388
                  $v_extract = true;
3389
              }
3390
          }
3391
      }
3392
3393
      // ----- Look for extract by ereg rule
3394
      // ereg() is deprecated with PHP 5.3
3395
      /*
3396
      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
3397
               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3398
3399
          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3400
              $v_extract = true;
3401
          }
3402
      }
3403
      */
3404
3405
      // ----- Look for extract by preg rule
3406 View Code Duplication
      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
3407
               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3408
3409
          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3410
              $v_extract = true;
3411
          }
3412
      }
3413
3414
      // ----- Look for extract by index rule
3415
      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3416
               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3417
3418
          // ----- Look if the index is in the list
3419
          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3420
3421
              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3422
                  $v_extract = true;
3423
              }
3424
              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3425
                  $j_start = $j+1;
3426
              }
3427
3428
              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3429
                  break;
3430
              }
3431
          }
3432
      }
3433
3434
      // ----- Look for no rule, which means extract all the archive
3435
      else {
3436
          $v_extract = true;
3437
      }
3438
3439
	  // ----- Check compression method
3440
	  if (   ($v_extract)
3441
	      && (   ($v_header['compression'] != 8)
3442
		      && ($v_header['compression'] != 0))) {
3443
          $v_header['status'] = 'unsupported_compression';
3444
3445
          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3446
          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3447
		      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3448
3449
              $this->privSwapBackMagicQuotes();
3450
3451
              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3452
			                       "Filename '".$v_header['stored_filename']."' is "
3453
				  	    	  	   ."compressed by an unsupported compression "
3454
				  	    	  	   ."method (".$v_header['compression'].") ");
3455
3456
              return PclZip::errorCode();
3457
		  }
3458
	  }
3459
3460
	  // ----- Check encrypted files
3461
	  if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3462
          $v_header['status'] = 'unsupported_encryption';
3463
3464
          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3465
          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3466
		      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3467
3468
              $this->privSwapBackMagicQuotes();
3469
3470
              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3471
			                       "Unsupported encryption for "
3472
				  	    	  	   ." filename '".$v_header['stored_filename']
3473
								   ."'");
3474
3475
              return PclZip::errorCode();
3476
		  }
3477
    }
3478
3479
      // ----- Look for real extraction
3480
      if (($v_extract) && ($v_header['status'] != 'ok')) {
3481
          $v_result = $this->privConvertHeader2FileInfo($v_header,
3482
		                                        $p_file_list[$v_nb_extracted++]);
3483
          if ($v_result != 1) {
3484
              $this->privCloseFd();
3485
              $this->privSwapBackMagicQuotes();
3486
              return $v_result;
3487
          }
3488
3489
          $v_extract = false;
3490
      }
3491
3492
      // ----- Look for real extraction
3493
      if ($v_extract)
3494
      {
3495
3496
        // ----- Go to the file position
3497
        @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
3498 View Code Duplication
        if (@fseek($this->zip_fd, $v_header['offset']))
3499
        {
3500
          // ----- Close the zip file
3501
          $this->privCloseFd();
3502
3503
          $this->privSwapBackMagicQuotes();
3504
3505
          // ----- Error log
3506
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3507
3508
          // ----- Return
3509
          return PclZip::errorCode();
3510
        }
3511
3512
        // ----- Look for extraction as string
3513
        if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3514
3515
          $v_string = '';
3516
3517
          // ----- Extracting the file
3518
          $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3519
          if ($v_result1 < 1) {
3520
            $this->privCloseFd();
3521
            $this->privSwapBackMagicQuotes();
3522
            return $v_result1;
3523
          }
3524
3525
          // ----- Get the only interesting attributes
3526 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3527
          {
3528
            // ----- Close the zip file
3529
            $this->privCloseFd();
3530
            $this->privSwapBackMagicQuotes();
3531
3532
            return $v_result;
3533
          }
3534
3535
          // ----- Set the file content
3536
          $p_file_list[$v_nb_extracted]['content'] = $v_string;
3537
3538
          // ----- Next extracted file
3539
          $v_nb_extracted++;
3540
3541
          // ----- Look for user callback abort
3542
          if ($v_result1 == 2) {
3543
          	break;
3544
          }
3545
        }
3546
        // ----- Look for extraction in standard output
3547
        elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3548
		        && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3549
          // ----- Extracting the file in standard output
3550
          $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3551
          if ($v_result1 < 1) {
3552
            $this->privCloseFd();
3553
            $this->privSwapBackMagicQuotes();
3554
            return $v_result1;
3555
          }
3556
3557
          // ----- Get the only interesting attributes
3558 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3559
            $this->privCloseFd();
3560
            $this->privSwapBackMagicQuotes();
3561
            return $v_result;
3562
          }
3563
3564
          // ----- Look for user callback abort
3565
          if ($v_result1 == 2) {
3566
          	break;
3567
          }
3568
        }
3569
        // ----- Look for normal extraction
3570
        else {
3571
          // ----- Extracting the file
3572
          $v_result1 = $this->privExtractFile($v_header,
3573
		                                      $p_path, $p_remove_path,
3574
											  $p_remove_all_path,
3575
											  $p_options);
3576
          if ($v_result1 < 1) {
3577
            $this->privCloseFd();
3578
            $this->privSwapBackMagicQuotes();
3579
            return $v_result1;
3580
          }
3581
3582
          // ----- Get the only interesting attributes
3583 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3584
          {
3585
            // ----- Close the zip file
3586
            $this->privCloseFd();
3587
            $this->privSwapBackMagicQuotes();
3588
3589
            return $v_result;
3590
          }
3591
3592
          // ----- Look for user callback abort
3593
          if ($v_result1 == 2) {
3594
          	break;
3595
          }
3596
        }
3597
      }
3598
    }
3599
3600
    // ----- Close the zip file
3601
    $this->privCloseFd();
3602
    $this->privSwapBackMagicQuotes();
3603
3604
    // ----- Return
3605
    return $v_result;
3606
  }
3607
  // --------------------------------------------------------------------------------
3608
3609
  // --------------------------------------------------------------------------------
3610
  // Function : privExtractFile()
3611
  // Description :
3612
  // Parameters :
3613
  // Return Values :
3614
  //
3615
  // 1 : ... ?
3616
  // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3617
  // --------------------------------------------------------------------------------
3618
  function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
3619
  {
3620
    $v_result=1;
3621
3622
    // ----- Read the file header
3623
    if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3624
    {
3625
      // ----- Return
3626
      return $v_result;
3627
    }
3628
3629
3630
    // ----- Check that the file header is coherent with $p_entry info
3631
    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3632
        // TBC
3633
    }
3634
3635
    // ----- Look for all path to remove
3636
    if ($p_remove_all_path == true) {
3637
        // ----- Look for folder entry that not need to be extracted
3638
        if (($p_entry['external']&0x00000010)==0x00000010) {
3639
3640
            $p_entry['status'] = "filtered";
3641
3642
            return $v_result;
3643
        }
3644
3645
        // ----- Get the basename of the path
3646
        $p_entry['filename'] = basename($p_entry['filename']);
3647
    }
3648
3649
    // ----- Look for path to remove
3650
    else if ($p_remove_path != "")
3651
    {
3652
      if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3653
      {
3654
3655
        // ----- Change the file status
3656
        $p_entry['status'] = "filtered";
3657
3658
        // ----- Return
3659
        return $v_result;
3660
      }
3661
3662
      $p_remove_path_size = strlen($p_remove_path);
3663
      if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3664
      {
3665
3666
        // ----- Remove the path
3667
        $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3668
3669
      }
3670
    }
3671
3672
    // ----- Add the path
3673
    if ($p_path != '') {
3674
      $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3675
    }
3676
3677
    // ----- Check a base_dir_restriction
3678
    if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3679
      $v_inclusion
3680
      = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3681
                                $p_entry['filename']);
3682 View Code Duplication
      if ($v_inclusion == 0) {
3683
3684
        PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3685
			                     "Filename '".$p_entry['filename']."' is "
3686
								 ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3687
3688
        return PclZip::errorCode();
3689
      }
3690
    }
3691
3692
    // ----- Look for pre-extract callback
3693 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3694
3695
      // ----- Generate a local information
3696
      $v_local_header = array();
3697
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3698
3699
      // ----- Call the callback
3700
      // Here I do not use call_user_func() because I need to send a reference to the
3701
      // header.
3702
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3703
      if ($v_result == 0) {
3704
        // ----- Change the file status
3705
        $p_entry['status'] = "skipped";
3706
        $v_result = 1;
3707
      }
3708
3709
      // ----- Look for abort result
3710
      if ($v_result == 2) {
3711
        // ----- This status is internal and will be changed in 'skipped'
3712
        $p_entry['status'] = "aborted";
3713
      	$v_result = PCLZIP_ERR_USER_ABORTED;
3714
      }
3715
3716
      // ----- Update the informations
3717
      // Only some fields can be modified
3718
      $p_entry['filename'] = $v_local_header['filename'];
3719
    }
3720
3721
3722
    // ----- Look if extraction should be done
3723
    if ($p_entry['status'] == 'ok') {
3724
3725
    // ----- Look for specific actions while the file exist
3726
    if (file_exists($p_entry['filename']))
3727
    {
3728
3729
      // ----- Look if file is a directory
3730
      if (is_dir($p_entry['filename']))
3731
      {
3732
3733
        // ----- Change the file status
3734
        $p_entry['status'] = "already_a_directory";
3735
3736
        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3737
        // For historical reason first PclZip implementation does not stop
3738
        // when this kind of error occurs.
3739 View Code Duplication
        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3740
		    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3741
3742
            PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3743
			                     "Filename '".$p_entry['filename']."' is "
3744
								 ."already used by an existing directory");
3745
3746
            return PclZip::errorCode();
3747
		    }
3748
      }
3749
      // ----- Look if file is write protected
3750
      else if (!is_writeable($p_entry['filename']))
3751
      {
3752
3753
        // ----- Change the file status
3754
        $p_entry['status'] = "write_protected";
3755
3756
        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3757
        // For historical reason first PclZip implementation does not stop
3758
        // when this kind of error occurs.
3759 View Code Duplication
        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3760
		    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3761
3762
            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3763
			                     "Filename '".$p_entry['filename']."' exists "
3764
								 ."and is write protected");
3765
3766
            return PclZip::errorCode();
3767
		    }
3768
      }
3769
3770
      // ----- Look if the extracted file is older
3771
      else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3772
      {
3773
        // ----- Change the file status
3774
        if (   (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
3775
		    && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3776
	  	  }
3777 View Code Duplication
		    else {
3778
            $p_entry['status'] = "newer_exist";
3779
3780
            // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3781
            // For historical reason first PclZip implementation does not stop
3782
            // when this kind of error occurs.
3783
            if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3784
		        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3785
3786
                PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3787
			             "Newer version of '".$p_entry['filename']."' exists "
3788
					    ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3789
3790
                return PclZip::errorCode();
3791
		      }
3792
		    }
3793
      }
3794
      else {
3795
      }
3796
    }
3797
3798
    // ----- Check the directory availability and create it if necessary
3799
    else {
3800
      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3801
        $v_dir_to_check = $p_entry['filename'];
3802
      else if (!strstr($p_entry['filename'], "/"))
3803
        $v_dir_to_check = "";
3804
      else
3805
        $v_dir_to_check = dirname($p_entry['filename']);
3806
3807
        if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3808
3809
          // ----- Change the file status
3810
          $p_entry['status'] = "path_creation_fail";
3811
3812
          // ----- Return
3813
          //return $v_result;
3814
          $v_result = 1;
3815
        }
3816
      }
3817
    }
3818
3819
    // ----- Look if extraction should be done
3820
    if ($p_entry['status'] == 'ok') {
3821
3822
      // ----- Do the extraction (if not a folder)
3823
      if (!(($p_entry['external']&0x00000010)==0x00000010))
3824
      {
3825
        // ----- Look for not compressed file
3826
        if ($p_entry['compression'] == 0) {
3827
3828
    		  // ----- Opening destination file
3829 View Code Duplication
          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3830
          {
3831
3832
            // ----- Change the file status
3833
            $p_entry['status'] = "write_error";
3834
3835
            // ----- Return
3836
            return $v_result;
3837
          }
3838
3839
3840
          // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3841
          $v_size = $p_entry['compressed_size'];
3842 View Code Duplication
          while ($v_size != 0)
3843
          {
3844
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3845
            $v_buffer = @fread($this->zip_fd, $v_read_size);
3846
            /* Try to speed up the code
3847
            $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3848
            @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3849
            */
3850
            @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 here. This can introduce security issues, and is generally not recommended.

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...
3851
            $v_size -= $v_read_size;
3852
          }
3853
3854
          // ----- Closing the destination file
3855
          fclose($v_dest_file);
3856
3857
          // ----- Change the file mtime
3858
          touch($p_entry['filename'], $p_entry['mtime']);
3859
3860
3861
        }
3862
        else {
3863
          // ----- TBC
3864
          // Need to be finished
3865 View Code Duplication
          if (($p_entry['flag'] & 1) == 1) {
3866
            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
3867
            return PclZip::errorCode();
3868
          }
3869
3870
3871
          // ----- Look for using temporary file to unzip
3872
          if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
3873
              && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
3874
                  || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
3875
                      && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
3876
            $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3877
            if ($v_result < PCLZIP_ERR_NO_ERROR) {
3878
              return $v_result;
3879
            }
3880
          }
3881
3882
          // ----- Look for extract in memory
3883
          else {
3884
3885
3886
            // ----- Read the compressed file in a buffer (one shot)
3887
            $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3888
3889
            // ----- Decompress the file
3890
            $v_file_content = @gzinflate($v_buffer);
3891
            unset($v_buffer);
3892
            if ($v_file_content === FALSE) {
3893
3894
              // ----- Change the file status
3895
              // TBC
3896
              $p_entry['status'] = "error";
3897
3898
              return $v_result;
3899
            }
3900
3901
            // ----- Opening destination file
3902 View Code Duplication
            if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3903
3904
              // ----- Change the file status
3905
              $p_entry['status'] = "write_error";
3906
3907
              return $v_result;
3908
            }
3909
3910
            // ----- Write the uncompressed data
3911
            @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
3912
            unset($v_file_content);
3913
3914
            // ----- Closing the destination file
3915
            @fclose($v_dest_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
3916
3917
          }
3918
3919
          // ----- Change the file mtime
3920
          @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 here. This can introduce security issues, and is generally not recommended.

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...
3921
        }
3922
3923
        // ----- Look for chmod option
3924
        if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3925
3926
          // ----- Change the mode of the file
3927
          @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 here. This can introduce security issues, and is generally not recommended.

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...
3928
        }
3929
3930
      }
3931
    }
3932
3933
  	// ----- Change abort status
3934 View Code Duplication
  	if ($p_entry['status'] == "aborted") {
3935
        $p_entry['status'] = "skipped";
3936
  	}
3937
3938
    // ----- Look for post-extract callback
3939
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3940
3941
      // ----- Generate a local information
3942
      $v_local_header = array();
3943
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3944
3945
      // ----- Call the callback
3946
      // Here I do not use call_user_func() because I need to send a reference to the
3947
      // header.
3948
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3949
3950
      // ----- Look for abort result
3951
      if ($v_result == 2) {
3952
      	$v_result = PCLZIP_ERR_USER_ABORTED;
3953
      }
3954
    }
3955
3956
    // ----- Return
3957
    return $v_result;
3958
  }
3959
  // --------------------------------------------------------------------------------
3960
3961
  // --------------------------------------------------------------------------------
3962
  // Function : privExtractFileUsingTempFile()
3963
  // Description :
3964
  // Parameters :
3965
  // Return Values :
3966
  // --------------------------------------------------------------------------------
3967
  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.

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

Loading history...
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
3968
  {
3969
    $v_result=1;
3970
3971
    // ----- Creates a temporary file
3972
    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
3973 View Code Duplication
    if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3974
      fclose($v_file);
0 ignored issues
show
Bug introduced by
The variable $v_file does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
3975
      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
3976
      return PclZip::errorCode();
3977
    }
3978
3979
3980
    // ----- Write gz file format header
3981
    $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
3982
    @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 here. This can introduce security issues, and is generally not recommended.

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...
3983
3984
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3985
    $v_size = $p_entry['compressed_size'];
3986 View Code Duplication
    while ($v_size != 0)
3987
    {
3988
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3989
      $v_buffer = @fread($this->zip_fd, $v_read_size);
3990
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
3991
      @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 here. This can introduce security issues, and is generally not recommended.

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...
3992
      $v_size -= $v_read_size;
3993
    }
3994
3995
    // ----- Write gz file format footer
3996
    $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
3997
    @fwrite($v_dest_file, $v_binary_data, 8);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
3998
3999
    // ----- Close the temporary file
4000
    @fclose($v_dest_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4001
4002
    // ----- Opening destination file
4003 View Code Duplication
    if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
4004
      $p_entry['status'] = "write_error";
4005
      return $v_result;
4006
    }
4007
4008
    // ----- Open the temporary gz file
4009 View Code Duplication
    if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
4010
      @fclose($v_dest_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4011
      $p_entry['status'] = "read_error";
4012
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
4013
      return PclZip::errorCode();
4014
    }
4015
4016
4017
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4018
    $v_size = $p_entry['size'];
4019 View Code Duplication
    while ($v_size != 0) {
4020
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4021
      $v_buffer = @gzread($v_src_file, $v_read_size);
4022
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4023
      @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 here. This can introduce security issues, and is generally not recommended.

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...
4024
      $v_size -= $v_read_size;
4025
    }
4026
    @fclose($v_dest_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4027
    @gzclose($v_src_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4028
4029
    // ----- Delete the temporary file
4030
    @unlink($v_gzip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4031
4032
    // ----- Return
4033
    return $v_result;
4034
  }
4035
  // --------------------------------------------------------------------------------
4036
4037
  // --------------------------------------------------------------------------------
4038
  // Function : privExtractFileInOutput()
4039
  // Description :
4040
  // Parameters :
4041
  // Return Values :
4042
  // --------------------------------------------------------------------------------
4043
  function privExtractFileInOutput(&$p_entry, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
4044
  {
4045
    $v_result=1;
4046
4047
    // ----- Read the file header
4048
    if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
4049
      return $v_result;
4050
    }
4051
4052
4053
    // ----- Check that the file header is coherent with $p_entry info
4054
    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4055
        // TBC
4056
    }
4057
4058
    // ----- Look for pre-extract callback
4059 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4060
4061
      // ----- Generate a local information
4062
      $v_local_header = array();
4063
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4064
4065
      // ----- Call the callback
4066
      // Here I do not use call_user_func() because I need to send a reference to the
4067
      // header.
4068
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4069
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4070
      if ($v_result == 0) {
4071
        // ----- Change the file status
4072
        $p_entry['status'] = "skipped";
4073
        $v_result = 1;
4074
      }
4075
4076
      // ----- Look for abort result
4077
      if ($v_result == 2) {
4078
        // ----- This status is internal and will be changed in 'skipped'
4079
        $p_entry['status'] = "aborted";
4080
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4081
      }
4082
4083
      // ----- Update the informations
4084
      // Only some fields can be modified
4085
      $p_entry['filename'] = $v_local_header['filename'];
4086
    }
4087
4088
    // ----- Trace
4089
4090
    // ----- Look if extraction should be done
4091
    if ($p_entry['status'] == 'ok') {
4092
4093
      // ----- Do the extraction (if not a folder)
4094
      if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4095
        // ----- Look for not compressed file
4096
        if ($p_entry['compressed_size'] == $p_entry['size']) {
4097
4098
          // ----- Read the file in a buffer (one shot)
4099
          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4100
4101
          // ----- Send the file to the output
4102
          echo $v_buffer;
4103
          unset($v_buffer);
4104
        }
4105
        else {
4106
4107
          // ----- Read the compressed file in a buffer (one shot)
4108
          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4109
4110
          // ----- Decompress the file
4111
          $v_file_content = gzinflate($v_buffer);
4112
          unset($v_buffer);
4113
4114
          // ----- Send the file to the output
4115
          echo $v_file_content;
4116
          unset($v_file_content);
4117
        }
4118
      }
4119
    }
4120
4121
	// ----- Change abort status
4122 View Code Duplication
	if ($p_entry['status'] == "aborted") {
4123
      $p_entry['status'] = "skipped";
4124
	}
4125
4126
    // ----- Look for post-extract callback
4127
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4128
4129
      // ----- Generate a local information
4130
      $v_local_header = array();
4131
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4132
4133
      // ----- Call the callback
4134
      // Here I do not use call_user_func() because I need to send a reference to the
4135
      // header.
4136
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4137
4138
      // ----- Look for abort result
4139
      if ($v_result == 2) {
4140
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4141
      }
4142
    }
4143
4144
    return $v_result;
4145
  }
4146
  // --------------------------------------------------------------------------------
4147
4148
  // --------------------------------------------------------------------------------
4149
  // Function : privExtractFileAsString()
4150
  // Description :
4151
  // Parameters :
4152
  // Return Values :
4153
  // --------------------------------------------------------------------------------
4154
  function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
4155
  {
4156
    $v_result=1;
4157
4158
    // ----- Read the file header
4159
    $v_header = array();
4160
    if (($v_result = $this->privReadFileHeader($v_header)) != 1)
4161
    {
4162
      // ----- Return
4163
      return $v_result;
4164
    }
4165
4166
4167
    // ----- Check that the file header is coherent with $p_entry info
4168
    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4169
        // TBC
4170
    }
4171
4172
    // ----- Look for pre-extract callback
4173 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4174
4175
      // ----- Generate a local information
4176
      $v_local_header = array();
4177
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4178
4179
      // ----- Call the callback
4180
      // Here I do not use call_user_func() because I need to send a reference to the
4181
      // header.
4182
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4183
      if ($v_result == 0) {
4184
        // ----- Change the file status
4185
        $p_entry['status'] = "skipped";
4186
        $v_result = 1;
4187
      }
4188
4189
      // ----- Look for abort result
4190
      if ($v_result == 2) {
4191
        // ----- This status is internal and will be changed in 'skipped'
4192
        $p_entry['status'] = "aborted";
4193
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4194
      }
4195
4196
      // ----- Update the informations
4197
      // Only some fields can be modified
4198
      $p_entry['filename'] = $v_local_header['filename'];
4199
    }
4200
4201
4202
    // ----- Look if extraction should be done
4203
    if ($p_entry['status'] == 'ok') {
4204
4205
      // ----- Do the extraction (if not a folder)
4206
      if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4207
        // ----- Look for not compressed file
4208
  //      if ($p_entry['compressed_size'] == $p_entry['size'])
4209
        if ($p_entry['compression'] == 0) {
4210
4211
          // ----- Reading the file
4212
          $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4213
        }
4214
        else {
4215
4216
          // ----- Reading the file
4217
          $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4218
4219
          // ----- Decompress the file
4220
          if (($p_string = @gzinflate($v_data)) === FALSE) {
4221
              // TBC
4222
          }
4223
        }
4224
4225
        // ----- Trace
4226
      }
4227
      else {
4228
          // TBC : error : can not extract a folder in a string
4229
      }
4230
4231
    }
4232
4233
  	// ----- Change abort status
4234 View Code Duplication
  	if ($p_entry['status'] == "aborted") {
4235
        $p_entry['status'] = "skipped";
4236
  	}
4237
4238
    // ----- Look for post-extract callback
4239
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4240
4241
      // ----- Generate a local information
4242
      $v_local_header = array();
4243
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4244
4245
      // ----- Swap the content to header
4246
      $v_local_header['content'] = $p_string;
4247
      $p_string = '';
4248
4249
      // ----- Call the callback
4250
      // Here I do not use call_user_func() because I need to send a reference to the
4251
      // header.
4252
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4253
4254
      // ----- Swap back the content to header
4255
      $p_string = $v_local_header['content'];
4256
      unset($v_local_header['content']);
4257
4258
      // ----- Look for abort result
4259
      if ($v_result == 2) {
4260
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4261
      }
4262
    }
4263
4264
    // ----- Return
4265
    return $v_result;
4266
  }
4267
  // --------------------------------------------------------------------------------
4268
4269
  // --------------------------------------------------------------------------------
4270
  // Function : privReadFileHeader()
4271
  // Description :
4272
  // Parameters :
4273
  // Return Values :
4274
  // --------------------------------------------------------------------------------
4275
  function privReadFileHeader(&$p_header)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
4276
  {
4277
    $v_result=1;
4278
4279
    // ----- Read the 4 bytes signature
4280
    $v_binary_data = @fread($this->zip_fd, 4);
4281
    $v_data = unpack('Vid', $v_binary_data);
4282
4283
    // ----- Check signature
4284
    if ($v_data['id'] != 0x04034b50)
4285
    {
4286
4287
      // ----- Error log
4288
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4289
4290
      // ----- Return
4291
      return PclZip::errorCode();
4292
    }
4293
4294
    // ----- Read the first 42 bytes of the header
4295
    $v_binary_data = fread($this->zip_fd, 26);
4296
4297
    // ----- Look for invalid block size
4298 View Code Duplication
    if (strlen($v_binary_data) != 26)
4299
    {
4300
      $p_header['filename'] = "";
4301
      $p_header['status'] = "invalid_header";
4302
4303
      // ----- Error log
4304
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4305
4306
      // ----- Return
4307
      return PclZip::errorCode();
4308
    }
4309
4310
    // ----- Extract the values
4311
    $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4312
4313
    // ----- Get filename
4314
    $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4315
4316
    // ----- Get extra_fields
4317
    if ($v_data['extra_len'] != 0) {
4318
      $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4319
    }
4320
    else {
4321
      $p_header['extra'] = '';
4322
    }
4323
4324
    // ----- Extract properties
4325
    $p_header['version_extracted'] = $v_data['version'];
4326
    $p_header['compression'] = $v_data['compression'];
4327
    $p_header['size'] = $v_data['size'];
4328
    $p_header['compressed_size'] = $v_data['compressed_size'];
4329
    $p_header['crc'] = $v_data['crc'];
4330
    $p_header['flag'] = $v_data['flag'];
4331
    $p_header['filename_len'] = $v_data['filename_len'];
4332
4333
    // ----- Recuperate date in UNIX format
4334
    $p_header['mdate'] = $v_data['mdate'];
4335
    $p_header['mtime'] = $v_data['mtime'];
4336
    if ($p_header['mdate'] && $p_header['mtime'])
4337
    {
4338
      // ----- Extract time
4339
      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4340
      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4341
      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4342
4343
      // ----- Extract date
4344
      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4345
      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4346
      $v_day = $p_header['mdate'] & 0x001F;
4347
4348
      // ----- Get UNIX date format
4349
      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4350
4351
    }
4352
    else
4353
    {
4354
      $p_header['mtime'] = time();
4355
    }
4356
4357
    // TBC
4358
    //for(reset($v_data); $key = key($v_data); next($v_data)) {
4359
    //}
4360
4361
    // ----- Set the stored filename
4362
    $p_header['stored_filename'] = $p_header['filename'];
4363
4364
    // ----- Set the status field
4365
    $p_header['status'] = "ok";
4366
4367
    // ----- Return
4368
    return $v_result;
4369
  }
4370
  // --------------------------------------------------------------------------------
4371
4372
  // --------------------------------------------------------------------------------
4373
  // Function : privReadCentralFileHeader()
4374
  // Description :
4375
  // Parameters :
4376
  // Return Values :
4377
  // --------------------------------------------------------------------------------
4378
  function privReadCentralFileHeader(&$p_header)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
4379
  {
4380
    $v_result=1;
4381
4382
    // ----- Read the 4 bytes signature
4383
    $v_binary_data = @fread($this->zip_fd, 4);
4384
    $v_data = unpack('Vid', $v_binary_data);
4385
4386
    // ----- Check signature
4387
    if ($v_data['id'] != 0x02014b50)
4388
    {
4389
4390
      // ----- Error log
4391
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4392
4393
      // ----- Return
4394
      return PclZip::errorCode();
4395
    }
4396
4397
    // ----- Read the first 42 bytes of the header
4398
    $v_binary_data = fread($this->zip_fd, 42);
4399
4400
    // ----- Look for invalid block size
4401 View Code Duplication
    if (strlen($v_binary_data) != 42)
4402
    {
4403
      $p_header['filename'] = "";
4404
      $p_header['status'] = "invalid_header";
4405
4406
      // ----- Error log
4407
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4408
4409
      // ----- Return
4410
      return PclZip::errorCode();
4411
    }
4412
4413
    // ----- Extract the values
4414
    $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);
4415
4416
    // ----- Get filename
4417 View Code Duplication
    if ($p_header['filename_len'] != 0)
4418
      $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4419
    else
4420
      $p_header['filename'] = '';
4421
4422
    // ----- Get extra
4423 View Code Duplication
    if ($p_header['extra_len'] != 0)
4424
      $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4425
    else
4426
      $p_header['extra'] = '';
4427
4428
    // ----- Get comment
4429 View Code Duplication
    if ($p_header['comment_len'] != 0)
4430
      $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4431
    else
4432
      $p_header['comment'] = '';
4433
4434
    // ----- Extract properties
4435
4436
    // ----- Recuperate date in UNIX format
4437
    //if ($p_header['mdate'] && $p_header['mtime'])
4438
    // TBC : bug : this was ignoring time with 0/0/0
4439
    if (1)
4440
    {
4441
      // ----- Extract time
4442
      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4443
      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4444
      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4445
4446
      // ----- Extract date
4447
      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4448
      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4449
      $v_day = $p_header['mdate'] & 0x001F;
4450
4451
      // ----- Get UNIX date format
4452
      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4453
4454
    }
4455
    else
4456
    {
4457
      $p_header['mtime'] = time();
4458
    }
4459
4460
    // ----- Set the stored filename
4461
    $p_header['stored_filename'] = $p_header['filename'];
4462
4463
    // ----- Set default status to ok
4464
    $p_header['status'] = 'ok';
4465
4466
    // ----- Look if it is a directory
4467
    if (substr($p_header['filename'], -1) == '/') {
4468
      //$p_header['external'] = 0x41FF0010;
4469
      $p_header['external'] = 0x00000010;
4470
    }
4471
4472
4473
    // ----- Return
4474
    return $v_result;
4475
  }
4476
  // --------------------------------------------------------------------------------
4477
4478
  // --------------------------------------------------------------------------------
4479
  // Function : privCheckFileHeaders()
4480
  // Description :
4481
  // Parameters :
4482
  // Return Values :
4483
  //   1 on success,
4484
  //   0 on error;
4485
  // --------------------------------------------------------------------------------
4486
  function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4487
  {
4488
    $v_result=1;
4489
4490
  	// ----- Check the static values
4491
  	// TBC
4492
  	if ($p_local_header['filename'] != $p_central_header['filename']) {
4493
  	}
4494
  	if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4495
  	}
4496
  	if ($p_local_header['flag'] != $p_central_header['flag']) {
4497
  	}
4498
  	if ($p_local_header['compression'] != $p_central_header['compression']) {
4499
  	}
4500
  	if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4501
  	}
4502
  	if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4503
  	}
4504
4505
  	// ----- Look for flag bit 3
4506
  	if (($p_local_header['flag'] & 8) == 8) {
4507
          $p_local_header['size'] = $p_central_header['size'];
4508
          $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4509
          $p_local_header['crc'] = $p_central_header['crc'];
4510
  	}
4511
4512
    // ----- Return
4513
    return $v_result;
4514
  }
4515
  // --------------------------------------------------------------------------------
4516
4517
  // --------------------------------------------------------------------------------
4518
  // Function : privReadEndCentralDir()
4519
  // Description :
4520
  // Parameters :
4521
  // Return Values :
4522
  // --------------------------------------------------------------------------------
4523
  function privReadEndCentralDir(&$p_central_dir)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
4524
  {
4525
    $v_result=1;
4526
4527
    // ----- Go to the end of the zip file
4528
    $v_size = filesize($this->zipname);
4529
    @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 here. This can introduce security issues, and is generally not recommended.

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...
4530 View Code Duplication
    if (@ftell($this->zip_fd) != $v_size)
4531
    {
4532
      // ----- Error log
4533
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4534
4535
      // ----- Return
4536
      return PclZip::errorCode();
4537
    }
4538
4539
    // ----- First try : look if this is an archive with no commentaries (most of the time)
4540
    // in this case the end of central dir is at 22 bytes of the file end
4541
    $v_found = 0;
4542
    if ($v_size > 26) {
4543
      @fseek($this->zip_fd, $v_size-22);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4544 View Code Duplication
      if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4545
      {
4546
        // ----- Error log
4547
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4548
4549
        // ----- Return
4550
        return PclZip::errorCode();
4551
      }
4552
4553
      // ----- Read for bytes
4554
      $v_binary_data = @fread($this->zip_fd, 4);
4555
      $v_data = @unpack('Vid', $v_binary_data);
4556
4557
      // ----- Check signature
4558
      if ($v_data['id'] == 0x06054b50) {
4559
        $v_found = 1;
4560
      }
4561
4562
      $v_pos = ftell($this->zip_fd);
4563
    }
4564
4565
    // ----- Go back to the maximum possible size of the Central Dir End Record
4566
    if (!$v_found) {
4567
      $v_maximum_size = 65557; // 0xFFFF + 22;
4568
      if ($v_maximum_size > $v_size)
4569
        $v_maximum_size = $v_size;
4570
      @fseek($this->zip_fd, $v_size-$v_maximum_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4571 View Code Duplication
      if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4572
      {
4573
        // ----- Error log
4574
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4575
4576
        // ----- Return
4577
        return PclZip::errorCode();
4578
      }
4579
4580
      // ----- Read byte per byte in order to find the signature
4581
      $v_pos = ftell($this->zip_fd);
4582
      $v_bytes = 0x00000000;
4583
      while ($v_pos < $v_size)
4584
      {
4585
        // ----- Read a byte
4586
        $v_byte = @fread($this->zip_fd, 1);
4587
4588
        // -----  Add the byte
4589
        //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
4590
        // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
4591
        // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
4592
        $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
4593
4594
        // ----- Compare the bytes
4595
        if ($v_bytes == 0x504b0506)
4596
        {
4597
          $v_pos++;
4598
          break;
4599
        }
4600
4601
        $v_pos++;
4602
      }
4603
4604
      // ----- Look if not found end of central dir
4605
      if ($v_pos == $v_size)
4606
      {
4607
4608
        // ----- Error log
4609
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4610
4611
        // ----- Return
4612
        return PclZip::errorCode();
4613
      }
4614
    }
4615
4616
    // ----- Read the first 18 bytes of the header
4617
    $v_binary_data = fread($this->zip_fd, 18);
4618
4619
    // ----- Look for invalid block size
4620 View Code Duplication
    if (strlen($v_binary_data) != 18)
4621
    {
4622
4623
      // ----- Error log
4624
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4625
4626
      // ----- Return
4627
      return PclZip::errorCode();
4628
    }
4629
4630
    // ----- Extract the values
4631
    $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4632
4633
    // ----- Check the global size
4634
    if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
0 ignored issues
show
Bug introduced by
The variable $v_pos does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
4635
4636
	  // ----- Removed in release 2.2 see readme file
4637
	  // The check of the file size is a little too strict.
4638
	  // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4639
	  // While decrypted, zip has training 0 bytes
4640
	  if (0) {
4641
      // ----- Error log
4642
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4643
	                       'The central dir is not at the end of the archive.'
4644
						   .' Some trailing bytes exists after the archive.');
4645
4646
      // ----- Return
4647
      return PclZip::errorCode();
4648
	  }
4649
    }
4650
4651
    // ----- Get comment
4652
    if ($v_data['comment_size'] != 0) {
4653
      $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4654
    }
4655
    else
4656
      $p_central_dir['comment'] = '';
4657
4658
    $p_central_dir['entries'] = $v_data['entries'];
4659
    $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4660
    $p_central_dir['offset'] = $v_data['offset'];
4661
    $p_central_dir['size'] = $v_data['size'];
4662
    $p_central_dir['disk'] = $v_data['disk'];
4663
    $p_central_dir['disk_start'] = $v_data['disk_start'];
4664
4665
    // TBC
4666
    //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4667
    //}
4668
4669
    // ----- Return
4670
    return $v_result;
4671
  }
4672
  // --------------------------------------------------------------------------------
4673
4674
  // --------------------------------------------------------------------------------
4675
  // Function : privDeleteByRule()
4676
  // Description :
4677
  // Parameters :
4678
  // Return Values :
4679
  // --------------------------------------------------------------------------------
4680
  function privDeleteByRule(&$p_result_list, &$p_options)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
4681
  {
4682
    $v_result=1;
4683
    $v_list_detail = array();
4684
4685
    // ----- Open the zip file
4686
    if (($v_result=$this->privOpenFd('rb')) != 1)
4687
    {
4688
      // ----- Return
4689
      return $v_result;
4690
    }
4691
4692
    // ----- Read the central directory informations
4693
    $v_central_dir = array();
4694
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4695
    {
4696
      $this->privCloseFd();
4697
      return $v_result;
4698
    }
4699
4700
    // ----- Go to beginning of File
4701
    @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4702
4703
    // ----- Scan all the files
4704
    // ----- Start at beginning of Central Dir
4705
    $v_pos_entry = $v_central_dir['offset'];
4706
    @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4707 View Code Duplication
    if (@fseek($this->zip_fd, $v_pos_entry))
4708
    {
4709
      // ----- Close the zip file
4710
      $this->privCloseFd();
4711
4712
      // ----- Error log
4713
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4714
4715
      // ----- Return
4716
      return PclZip::errorCode();
4717
    }
4718
4719
    // ----- Read each entry
4720
    $v_header_list = array();
4721
    $j_start = 0;
4722
    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4723
    {
4724
4725
      // ----- Read the file header
4726
      $v_header_list[$v_nb_extracted] = array();
4727
      if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4728
      {
4729
        // ----- Close the zip file
4730
        $this->privCloseFd();
4731
4732
        return $v_result;
4733
      }
4734
4735
4736
      // ----- Store the index
4737
      $v_header_list[$v_nb_extracted]['index'] = $i;
4738
4739
      // ----- Look for the specific extract rules
4740
      $v_found = false;
4741
4742
      // ----- Look for extract by name rule
4743
      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
4744
          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4745
4746
          // ----- Look if the filename is in the list
4747
          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4748
4749
              // ----- Look for a directory
4750
              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4751
4752
                  // ----- Look if the directory is in the filename path
4753
                  if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4754
                      && (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])) {
4755
                      $v_found = true;
4756
                  }
4757
                  elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4758
                          && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4759
                      $v_found = true;
4760
                  }
4761
              }
4762
              // ----- Look for a filename
4763
              elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4764
                  $v_found = true;
4765
              }
4766
          }
4767
      }
4768
4769
      // ----- Look for extract by ereg rule
4770
      // ereg() is deprecated with PHP 5.3
4771
      /*
4772
      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
4773
               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4774
4775
          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4776
              $v_found = true;
4777
          }
4778
      }
4779
      */
4780
4781
      // ----- Look for extract by preg rule
4782 View Code Duplication
      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
4783
               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4784
4785
          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4786
              $v_found = true;
4787
          }
4788
      }
4789
4790
      // ----- Look for extract by index rule
4791
      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4792
               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4793
4794
          // ----- Look if the index is in the list
4795
          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4796
4797
              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4798
                  $v_found = true;
4799
              }
4800
              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4801
                  $j_start = $j+1;
4802
              }
4803
4804
              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4805
                  break;
4806
              }
4807
          }
4808
      }
4809
      else {
4810
      	$v_found = true;
4811
      }
4812
4813
      // ----- Look for deletion
4814
      if ($v_found)
4815
      {
4816
        unset($v_header_list[$v_nb_extracted]);
4817
      }
4818
      else
4819
      {
4820
        $v_nb_extracted++;
4821
      }
4822
    }
4823
4824
    // ----- Look if something need to be deleted
4825
    if ($v_nb_extracted > 0) {
4826
4827
        // ----- Creates a temporay file
4828
        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4829
4830
        // ----- Creates a temporary zip archive
4831
        $v_temp_zip = new PclZip($v_zip_temp_name);
4832
4833
        // ----- Open the temporary zip file in write mode
4834
        if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4835
            $this->privCloseFd();
4836
4837
            // ----- Return
4838
            return $v_result;
4839
        }
4840
4841
        // ----- Look which file need to be kept
4842
        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...
4843
4844
            // ----- Calculate the position of the header
4845
            @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4846
            if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
4847
                // ----- Close the zip file
4848
                $this->privCloseFd();
4849
                $v_temp_zip->privCloseFd();
4850
                @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4851
4852
                // ----- Error log
4853
                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4854
4855
                // ----- Return
4856
                return PclZip::errorCode();
4857
            }
4858
4859
            // ----- Read the file header
4860
            $v_local_header = array();
4861
            if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4862
                // ----- Close the zip file
4863
                $this->privCloseFd();
4864
                $v_temp_zip->privCloseFd();
4865
                @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4866
4867
                // ----- Return
4868
                return $v_result;
4869
            }
4870
4871
            // ----- Check that local file header is same as central file header
4872
            if ($this->privCheckFileHeaders($v_local_header,
4873
			                                $v_header_list[$i]) != 1) {
4874
                // TBC
4875
            }
4876
            unset($v_local_header);
4877
4878
            // ----- Write the file header
4879 View Code Duplication
            if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4880
                // ----- Close the zip file
4881
                $this->privCloseFd();
4882
                $v_temp_zip->privCloseFd();
4883
                @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4884
4885
                // ----- Return
4886
                return $v_result;
4887
            }
4888
4889
            // ----- Read/write the data block
4890
            if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4891
                // ----- Close the zip file
4892
                $this->privCloseFd();
4893
                $v_temp_zip->privCloseFd();
4894
                @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4895
4896
                // ----- Return
4897
                return $v_result;
4898
            }
4899
        }
4900
4901
        // ----- Store the offset of the central dir
4902
        $v_offset = @ftell($v_temp_zip->zip_fd);
4903
4904
        // ----- Re-Create the Central Dir files header
4905
        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...
4906
            // ----- Create the file header
4907 View Code Duplication
            if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4908
                $v_temp_zip->privCloseFd();
4909
                $this->privCloseFd();
4910
                @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4911
4912
                // ----- Return
4913
                return $v_result;
4914
            }
4915
4916
            // ----- Transform the header to a 'usable' info
4917
            $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4918
        }
4919
4920
4921
        // ----- Zip file comment
4922
        $v_comment = '';
4923
        if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4924
          $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4925
        }
4926
4927
        // ----- Calculate the size of the central header
4928
        $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4929
4930
        // ----- Create the central dir footer
4931
        if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4932
            // ----- Reset the file list
4933
            unset($v_header_list);
4934
            $v_temp_zip->privCloseFd();
4935
            $this->privCloseFd();
4936
            @unlink($v_zip_temp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4937
4938
            // ----- Return
4939
            return $v_result;
4940
        }
4941
4942
        // ----- Close
4943
        $v_temp_zip->privCloseFd();
4944
        $this->privCloseFd();
4945
4946
        // ----- Delete the zip file
4947
        // TBC : I should test the result ...
4948
        @unlink($this->zipname);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
4949
4950
        // ----- Rename the temporary file
4951
        // TBC : I should test the result ...
4952
        //@rename($v_zip_temp_name, $this->zipname);
4953
        PclZipUtilRename($v_zip_temp_name, $this->zipname);
4954
4955
        // ----- Destroy the temporary archive
4956
        unset($v_temp_zip);
4957
    }
4958
4959
    // ----- Remove every files : reset the file
4960
    else if ($v_central_dir['entries'] != 0) {
4961
        $this->privCloseFd();
4962
4963
        if (($v_result = $this->privOpenFd('wb')) != 1) {
4964
          return $v_result;
4965
        }
4966
4967
        if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4968
          return $v_result;
4969
        }
4970
4971
        $this->privCloseFd();
4972
    }
4973
4974
    // ----- Return
4975
    return $v_result;
4976
  }
4977
  // --------------------------------------------------------------------------------
4978
4979
  // --------------------------------------------------------------------------------
4980
  // Function : privDirCheck()
4981
  // Description :
4982
  //   Check if a directory exists, if not it creates it and all the parents directory
4983
  //   which may be useful.
4984
  // Parameters :
4985
  //   $p_dir : Directory path to check.
4986
  // Return Values :
4987
  //    1 : OK
4988
  //   -1 : Unable to create directory
4989
  // --------------------------------------------------------------------------------
4990
  function privDirCheck($p_dir, $p_is_dir=false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
4991
  {
4992
    $v_result = 1;
4993
4994
4995
    // ----- Remove the final '/'
4996
    if (($p_is_dir) && (substr($p_dir, -1)=='/'))
4997
    {
4998
      $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
4999
    }
5000
5001
    // ----- Check the directory availability
5002
    if ((is_dir($p_dir)) || ($p_dir == ""))
5003
    {
5004
      return 1;
5005
    }
5006
5007
    // ----- Extract parent directory
5008
    $p_parent_dir = dirname($p_dir);
5009
5010
    // ----- Just a check
5011
    if ($p_parent_dir != $p_dir)
5012
    {
5013
      // ----- Look for parent directory
5014
      if ($p_parent_dir != "")
5015
      {
5016
        if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
5017
        {
5018
          return $v_result;
5019
        }
5020
      }
5021
    }
5022
5023
    // ----- Create the directory
5024
    if (!@mkdir($p_dir, 0777))
5025
    {
5026
      // ----- Error log
5027
      PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
5028
5029
      // ----- Return
5030
      return PclZip::errorCode();
5031
    }
5032
5033
    // ----- Return
5034
    return $v_result;
5035
  }
5036
  // --------------------------------------------------------------------------------
5037
5038
  // --------------------------------------------------------------------------------
5039
  // Function : privMerge()
5040
  // Description :
5041
  //   If $p_archive_to_add does not exist, the function exit with a success result.
5042
  // Parameters :
5043
  // Return Values :
5044
  // --------------------------------------------------------------------------------
5045
  function privMerge(&$p_archive_to_add)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
5046
  {
5047
    $v_result=1;
5048
5049
    // ----- Look if the archive_to_add exists
5050
    if (!is_file($p_archive_to_add->zipname))
5051
    {
5052
5053
      // ----- Nothing to merge, so merge is a success
5054
      $v_result = 1;
5055
5056
      // ----- Return
5057
      return $v_result;
5058
    }
5059
5060
    // ----- Look if the archive exists
5061
    if (!is_file($this->zipname))
5062
    {
5063
5064
      // ----- Do a duplicate
5065
      $v_result = $this->privDuplicate($p_archive_to_add->zipname);
5066
5067
      // ----- Return
5068
      return $v_result;
5069
    }
5070
5071
    // ----- Open the zip file
5072
    if (($v_result=$this->privOpenFd('rb')) != 1)
5073
    {
5074
      // ----- Return
5075
      return $v_result;
5076
    }
5077
5078
    // ----- Read the central directory informations
5079
    $v_central_dir = array();
5080
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
5081
    {
5082
      $this->privCloseFd();
5083
      return $v_result;
5084
    }
5085
5086
    // ----- Go to beginning of File
5087
    @rewind($this->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5088
5089
    // ----- Open the archive_to_add file
5090
    if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
5091
    {
5092
      $this->privCloseFd();
5093
5094
      // ----- Return
5095
      return $v_result;
5096
    }
5097
5098
    // ----- Read the central directory informations
5099
    $v_central_dir_to_add = array();
5100
    if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5101
    {
5102
      $this->privCloseFd();
5103
      $p_archive_to_add->privCloseFd();
5104
5105
      return $v_result;
5106
    }
5107
5108
    // ----- Go to beginning of File
5109
    @rewind($p_archive_to_add->zip_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5110
5111
    // ----- Creates a temporay file
5112
    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
5113
5114
    // ----- Open the temporary file in write mode
5115
    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
5116
    {
5117
      $this->privCloseFd();
5118
      $p_archive_to_add->privCloseFd();
5119
5120
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
5121
5122
      // ----- Return
5123
      return PclZip::errorCode();
5124
    }
5125
5126
    // ----- Copy the files from the archive to the temporary file
5127
    // TBC : Here I should better append the file and go back to erase the central dir
5128
    $v_size = $v_central_dir['offset'];
5129
    while ($v_size != 0)
5130
    {
5131
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5132
      $v_buffer = fread($this->zip_fd, $v_read_size);
5133
      @fwrite($v_zip_temp_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 here. This can introduce security issues, and is generally not recommended.

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...
5134
      $v_size -= $v_read_size;
5135
    }
5136
5137
    // ----- Copy the files from the archive_to_add into the temporary file
5138
    $v_size = $v_central_dir_to_add['offset'];
5139
    while ($v_size != 0)
5140
    {
5141
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5142
      $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
5143
      @fwrite($v_zip_temp_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 here. This can introduce security issues, and is generally not recommended.

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...
5144
      $v_size -= $v_read_size;
5145
    }
5146
5147
    // ----- Store the offset of the central dir
5148
    $v_offset = @ftell($v_zip_temp_fd);
5149
5150
    // ----- Copy the block of file headers from the old archive
5151
    $v_size = $v_central_dir['size'];
5152 View Code Duplication
    while ($v_size != 0)
5153
    {
5154
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5155
      $v_buffer = @fread($this->zip_fd, $v_read_size);
5156
      @fwrite($v_zip_temp_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 here. This can introduce security issues, and is generally not recommended.

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...
5157
      $v_size -= $v_read_size;
5158
    }
5159
5160
    // ----- Copy the block of file headers from the archive_to_add
5161
    $v_size = $v_central_dir_to_add['size'];
5162 View Code Duplication
    while ($v_size != 0)
5163
    {
5164
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5165
      $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
5166
      @fwrite($v_zip_temp_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 here. This can introduce security issues, and is generally not recommended.

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...
5167
      $v_size -= $v_read_size;
5168
    }
5169
5170
    // ----- Merge the file comments
5171
    $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
5172
5173
    // ----- Calculate the size of the (new) central header
5174
    $v_size = @ftell($v_zip_temp_fd)-$v_offset;
5175
5176
    // ----- Swap the file descriptor
5177
    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
5178
    // the following methods on the temporary fil and not the real archive fd
5179
    $v_swap = $this->zip_fd;
5180
    $this->zip_fd = $v_zip_temp_fd;
5181
    $v_zip_temp_fd = $v_swap;
5182
5183
    // ----- Create the central dir footer
5184
    if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
5185
    {
5186
      $this->privCloseFd();
5187
      $p_archive_to_add->privCloseFd();
5188
      @fclose($v_zip_temp_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5189
      $this->zip_fd = null;
5190
5191
      // ----- Reset the file list
5192
      unset($v_header_list);
5193
5194
      // ----- Return
5195
      return $v_result;
5196
    }
5197
5198
    // ----- Swap back the file descriptor
5199
    $v_swap = $this->zip_fd;
5200
    $this->zip_fd = $v_zip_temp_fd;
5201
    $v_zip_temp_fd = $v_swap;
5202
5203
    // ----- Close
5204
    $this->privCloseFd();
5205
    $p_archive_to_add->privCloseFd();
5206
5207
    // ----- Close the temporary file
5208
    @fclose($v_zip_temp_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5209
5210
    // ----- Delete the zip file
5211
    // TBC : I should test the result ...
5212
    @unlink($this->zipname);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5213
5214
    // ----- Rename the temporary file
5215
    // TBC : I should test the result ...
5216
    //@rename($v_zip_temp_name, $this->zipname);
5217
    PclZipUtilRename($v_zip_temp_name, $this->zipname);
5218
5219
    // ----- Return
5220
    return $v_result;
5221
  }
5222
  // --------------------------------------------------------------------------------
5223
5224
  // --------------------------------------------------------------------------------
5225
  // Function : privDuplicate()
5226
  // Description :
5227
  // Parameters :
5228
  // Return Values :
5229
  // --------------------------------------------------------------------------------
5230
  function privDuplicate($p_archive_filename)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
5231
  {
5232
    $v_result=1;
5233
5234
    // ----- Look if the $p_archive_filename exists
5235
    if (!is_file($p_archive_filename))
5236
    {
5237
5238
      // ----- Nothing to duplicate, so duplicate is a success.
5239
      $v_result = 1;
5240
5241
      // ----- Return
5242
      return $v_result;
5243
    }
5244
5245
    // ----- Open the zip file
5246
    if (($v_result=$this->privOpenFd('wb')) != 1)
5247
    {
5248
      // ----- Return
5249
      return $v_result;
5250
    }
5251
5252
    // ----- Open the temporary file in write mode
5253 View Code Duplication
    if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
5254
    {
5255
      $this->privCloseFd();
5256
5257
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
5258
5259
      // ----- Return
5260
      return PclZip::errorCode();
5261
    }
5262
5263
    // ----- Copy the files from the archive to the temporary file
5264
    // TBC : Here I should better append the file and go back to erase the central dir
5265
    $v_size = filesize($p_archive_filename);
5266
    while ($v_size != 0)
5267
    {
5268
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5269
      $v_buffer = fread($v_zip_temp_fd, $v_read_size);
5270
      @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 here. This can introduce security issues, and is generally not recommended.

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...
5271
      $v_size -= $v_read_size;
5272
    }
5273
5274
    // ----- Close
5275
    $this->privCloseFd();
5276
5277
    // ----- Close the temporary file
5278
    @fclose($v_zip_temp_fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5279
5280
    // ----- Return
5281
    return $v_result;
5282
  }
5283
  // --------------------------------------------------------------------------------
5284
5285
  // --------------------------------------------------------------------------------
5286
  // Function : privErrorLog()
5287
  // Description :
5288
  // Parameters :
5289
  // --------------------------------------------------------------------------------
5290
  function privErrorLog($p_error_code=0, $p_error_string='')
5291
  {
5292
    if (PCLZIP_ERROR_EXTERNAL == 1) {
5293
      PclError($p_error_code, $p_error_string);
5294
    }
5295
    else {
5296
      $this->error_code = $p_error_code;
5297
      $this->error_string = $p_error_string;
5298
    }
5299
  }
5300
  // --------------------------------------------------------------------------------
5301
5302
  // --------------------------------------------------------------------------------
5303
  // Function : privErrorReset()
5304
  // Description :
5305
  // Parameters :
5306
  // --------------------------------------------------------------------------------
5307
  function privErrorReset()
5308
  {
5309
    if (PCLZIP_ERROR_EXTERNAL == 1) {
5310
      PclErrorReset();
5311
    }
5312
    else {
5313
      $this->error_code = 0;
5314
      $this->error_string = '';
5315
    }
5316
  }
5317
  // --------------------------------------------------------------------------------
5318
5319
  // --------------------------------------------------------------------------------
5320
  // Function : privDisableMagicQuotes()
5321
  // Description :
5322
  // Parameters :
5323
  // Return Values :
5324
  // --------------------------------------------------------------------------------
5325 View Code Duplication
  function privDisableMagicQuotes()
5326
  {
5327
    $v_result=1;
5328
5329
    // ----- Look if function exists
5330
    if (   (!function_exists("get_magic_quotes_runtime"))
5331
	    || (!function_exists("set_magic_quotes_runtime"))) {
5332
      return $v_result;
5333
	}
5334
5335
    // ----- Look if already done
5336
    if ($this->magic_quotes_status != -1) {
5337
      return $v_result;
5338
	}
5339
5340
	// ----- Get and memorize the magic_quote value
5341
	$this->magic_quotes_status = @get_magic_quotes_runtime();
5342
5343
	// ----- Disable magic_quotes
5344
	if ($this->magic_quotes_status == 1) {
5345
	  @set_magic_quotes_runtime(0);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5346
	}
5347
5348
    // ----- Return
5349
    return $v_result;
5350
  }
5351
  // --------------------------------------------------------------------------------
5352
5353
  // --------------------------------------------------------------------------------
5354
  // Function : privSwapBackMagicQuotes()
5355
  // Description :
5356
  // Parameters :
5357
  // Return Values :
5358
  // --------------------------------------------------------------------------------
5359 View Code Duplication
  function privSwapBackMagicQuotes()
5360
  {
5361
    $v_result=1;
5362
5363
    // ----- Look if function exists
5364
    if (   (!function_exists("get_magic_quotes_runtime"))
5365
	    || (!function_exists("set_magic_quotes_runtime"))) {
5366
      return $v_result;
5367
	}
5368
5369
    // ----- Look if something to do
5370
    if ($this->magic_quotes_status != -1) {
5371
      return $v_result;
5372
	}
5373
5374
	// ----- Swap back magic_quotes
5375
	if ($this->magic_quotes_status == 1) {
5376
  	  @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 here. This can introduce security issues, and is generally not recommended.

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...
5377
	}
5378
5379
    // ----- Return
5380
    return $v_result;
5381
  }
5382
  // --------------------------------------------------------------------------------
5383
5384
  }
5385
  // End of class
5386
  // --------------------------------------------------------------------------------
5387
5388
  // --------------------------------------------------------------------------------
5389
  // Function : PclZipUtilPathReduction()
5390
  // Description :
5391
  // Parameters :
5392
  // Return Values :
5393
  // --------------------------------------------------------------------------------
5394
  function PclZipUtilPathReduction($p_dir)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
5395
  {
5396
    $v_result = "";
5397
5398
    // ----- Look for not empty path
5399
    if ($p_dir != "") {
5400
      // ----- Explode path by directory names
5401
      $v_list = explode("/", $p_dir);
5402
5403
      // ----- Study directories from last to first
5404
      $v_skip = 0;
5405
      for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5406
        // ----- Look for current path
5407
        if ($v_list[$i] == ".") {
5408
          // ----- Ignore this directory
5409
          // Should be the first $i=0, but no check is done
5410
        }
5411
        else if ($v_list[$i] == "..") {
5412
		  $v_skip++;
5413
        }
5414
        else if ($v_list[$i] == "") {
5415
		  // ----- First '/' i.e. root slash
5416
		  if ($i == 0) {
5417
            $v_result = "/".$v_result;
5418
		    if ($v_skip > 0) {
5419
		        // ----- It is an invalid path, so the path is not modified
5420
		        // TBC
5421
		        $v_result = $p_dir;
5422
                $v_skip = 0;
5423
		    }
5424
		  }
5425
		  // ----- Last '/' i.e. indicates a directory
5426
		  else if ($i == (sizeof($v_list)-1)) {
5427
            $v_result = $v_list[$i];
5428
		  }
5429
		  // ----- Double '/' inside the path
5430
		  else {
5431
            // ----- Ignore only the double '//' in path,
5432
            // but not the first and last '/'
5433
		  }
5434
        }
5435
        else {
5436
		  // ----- Look for item to skip
5437
		  if ($v_skip > 0) {
5438
		    $v_skip--;
5439
		  }
5440
		  else {
5441
            $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5442
		  }
5443
        }
5444
      }
5445
5446
      // ----- Look for skip
5447
      if ($v_skip > 0) {
5448
        while ($v_skip > 0) {
5449
            $v_result = '../'.$v_result;
5450
            $v_skip--;
5451
        }
5452
      }
5453
    }
5454
5455
    // ----- Return
5456
    return $v_result;
5457
  }
5458
  // --------------------------------------------------------------------------------
5459
5460
  // --------------------------------------------------------------------------------
5461
  // Function : PclZipUtilPathInclusion()
5462
  // Description :
5463
  //   This function indicates if the path $p_path is under the $p_dir tree. Or,
5464
  //   said in an other way, if the file or sub-dir $p_path is inside the dir
5465
  //   $p_dir.
5466
  //   The function indicates also if the path is exactly the same as the dir.
5467
  //   This function supports path with duplicated '/' like '//', but does not
5468
  //   support '.' or '..' statements.
5469
  // Parameters :
5470
  // Return Values :
5471
  //   0 if $p_path is not inside directory $p_dir
5472
  //   1 if $p_path is inside directory $p_dir
5473
  //   2 if $p_path is exactly the same as $p_dir
5474
  // --------------------------------------------------------------------------------
5475
  function PclZipUtilPathInclusion($p_dir, $p_path)
5476
  {
5477
    $v_result = 1;
5478
5479
    // ----- Look for path beginning by ./
5480 View Code Duplication
    if (   ($p_dir == '.')
5481
        || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
5482
      $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
5483
    }
5484 View Code Duplication
    if (   ($p_path == '.')
5485
        || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
5486
      $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
5487
    }
5488
5489
    // ----- Explode dir and path by directory separator
5490
    $v_list_dir = explode("/", $p_dir);
5491
    $v_list_dir_size = sizeof($v_list_dir);
5492
    $v_list_path = explode("/", $p_path);
5493
    $v_list_path_size = sizeof($v_list_path);
5494
5495
    // ----- Study directories paths
5496
    $i = 0;
5497
    $j = 0;
5498
    while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5499
5500
      // ----- Look for empty dir (path reduction)
5501
      if ($v_list_dir[$i] == '') {
5502
        $i++;
5503
        continue;
5504
      }
5505
      if ($v_list_path[$j] == '') {
5506
        $j++;
5507
        continue;
5508
      }
5509
5510
      // ----- Compare the items
5511
      if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {
5512
        $v_result = 0;
5513
      }
5514
5515
      // ----- Next items
5516
      $i++;
5517
      $j++;
5518
    }
5519
5520
    // ----- Look if everything seems to be the same
5521
    if ($v_result) {
5522
      // ----- Skip all the empty items
5523
      while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5524
      while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5525
5526
      if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5527
        // ----- There are exactly the same
5528
        $v_result = 2;
5529
      }
5530
      else if ($i < $v_list_dir_size) {
5531
        // ----- The path is shorter than the dir
5532
        $v_result = 0;
5533
      }
5534
    }
5535
5536
    // ----- Return
5537
    return $v_result;
5538
  }
5539
  // --------------------------------------------------------------------------------
5540
5541
  // --------------------------------------------------------------------------------
5542
  // Function : PclZipUtilCopyBlock()
5543
  // Description :
5544
  // Parameters :
5545
  //   $p_mode : read/write compression mode
5546
  //             0 : src & dest normal
5547
  //             1 : src gzip, dest normal
5548
  //             2 : src normal, dest gzip
5549
  //             3 : src & dest gzip
5550
  // Return Values :
5551
  // --------------------------------------------------------------------------------
5552
  function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5553
  {
5554
    $v_result = 1;
5555
5556
    if ($p_mode==0)
5557
    {
5558 View Code Duplication
      while ($p_size != 0)
5559
      {
5560
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5561
        $v_buffer = @fread($p_src, $v_read_size);
5562
        @fwrite($p_dest, $v_buffer, $v_read_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5563
        $p_size -= $v_read_size;
5564
      }
5565
    }
5566
    else if ($p_mode==1)
5567
    {
5568 View Code Duplication
      while ($p_size != 0)
5569
      {
5570
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5571
        $v_buffer = @gzread($p_src, $v_read_size);
5572
        @fwrite($p_dest, $v_buffer, $v_read_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5573
        $p_size -= $v_read_size;
5574
      }
5575
    }
5576
    else if ($p_mode==2)
5577
    {
5578 View Code Duplication
      while ($p_size != 0)
5579
      {
5580
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5581
        $v_buffer = @fread($p_src, $v_read_size);
5582
        @gzwrite($p_dest, $v_buffer, $v_read_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5583
        $p_size -= $v_read_size;
5584
      }
5585
    }
5586
    else if ($p_mode==3)
5587
    {
5588 View Code Duplication
      while ($p_size != 0)
5589
      {
5590
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5591
        $v_buffer = @gzread($p_src, $v_read_size);
5592
        @gzwrite($p_dest, $v_buffer, $v_read_size);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
5593
        $p_size -= $v_read_size;
5594
      }
5595
    }
5596
5597
    // ----- Return
5598
    return $v_result;
5599
  }
5600
  // --------------------------------------------------------------------------------
5601
5602
  // --------------------------------------------------------------------------------
5603
  // Function : PclZipUtilRename()
5604
  // Description :
5605
  //   This function tries to do a simple rename() function. If it fails, it
5606
  //   tries to copy the $p_src file in a new $p_dest file and then unlink the
5607
  //   first one.
5608
  // Parameters :
5609
  //   $p_src : Old filename
5610
  //   $p_dest : New filename
5611
  // Return Values :
5612
  //   1 on success, 0 on failure.
5613
  // --------------------------------------------------------------------------------
5614
  function PclZipUtilRename($p_src, $p_dest)
5615
  {
5616
    $v_result = 1;
5617
5618
    // ----- Try to rename the files
5619
    if (!@rename($p_src, $p_dest)) {
5620
5621
      // ----- Try to copy & unlink the src
5622
      if (!@copy($p_src, $p_dest)) {
5623
        $v_result = 0;
5624
      }
5625
      else if (!@unlink($p_src)) {
5626
        $v_result = 0;
5627
      }
5628
    }
5629
5630
    // ----- Return
5631
    return $v_result;
5632
  }
5633
  // --------------------------------------------------------------------------------
5634
5635
  // --------------------------------------------------------------------------------
5636
  // Function : PclZipUtilOptionText()
5637
  // Description :
5638
  //   Translate option value in text. Mainly for debug purpose.
5639
  // Parameters :
5640
  //   $p_option : the option value.
5641
  // Return Values :
5642
  //   The option text value.
5643
  // --------------------------------------------------------------------------------
5644
  function PclZipUtilOptionText($p_option)
5645
  {
5646
5647
    $v_list = get_defined_constants();
5648
    for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5649
	    $v_prefix = substr($v_key, 0, 10);
5650
	    if ((   ($v_prefix == 'PCLZIP_OPT')
5651
           || ($v_prefix == 'PCLZIP_CB_')
5652
           || ($v_prefix == 'PCLZIP_ATT'))
5653
	        && ($v_list[$v_key] == $p_option)) {
5654
        return $v_key;
5655
	    }
5656
    }
5657
5658
    $v_result = 'Unknown';
5659
5660
    return $v_result;
5661
  }
5662
  // --------------------------------------------------------------------------------
5663
5664
  // --------------------------------------------------------------------------------
5665
  // Function : PclZipUtilTranslateWinPath()
5666
  // Description :
5667
  //   Translate windows path by replacing '\' by '/' and optionally removing
5668
  //   drive letter.
5669
  // Parameters :
5670
  //   $p_path : path to translate.
5671
  //   $p_remove_disk_letter : true | false
5672
  // Return Values :
5673
  //   The path translated.
5674
  // --------------------------------------------------------------------------------
5675
  function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
5676
  {
5677
    if (stristr(php_uname(), 'windows')) {
5678
      // ----- Look for potential disk letter
5679
      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...
5680
          $p_path = substr($p_path, $v_position+1);
5681
      }
5682
      // ----- Change potential windows directory separator
5683
      if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5684
          $p_path = strtr($p_path, '\\', '/');
5685
      }
5686
    }
5687
    return $p_path;
5688
  }
5689
  // --------------------------------------------------------------------------------
5690
5691
5692
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
5693