PclZip::PclZip()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 17
rs 9.4285
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 = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $zipname.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
194
195
    // ----- File descriptor of the zip file
196
    var $zip_fd = 0;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $zip_fd.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
197
198
    // ----- Internal error handling
199
    var $error_code = 1;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $error_code.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
200
    var $error_string = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $error_string.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
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;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $magic_quotes_status.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
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 PclZip($p_zipname)
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
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 PclZip() 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
234
  // --------------------------------------------------------------------------------
235
  // Function :
236
  //   create($p_filelist, $p_add_dir="", $p_remove_dir="")
237
  //   create($p_filelist, $p_option, $p_option_value, ...)
238
  // Description :
239
  //   This method supports two different synopsis. The first one is historical.
240
  //   This method creates a Zip Archive. The Zip file is created in the
241
  //   filesystem. The files and directories indicated in $p_filelist
242
  //   are added in the archive. See the parameters description for the
243
  //   supported format of $p_filelist.
244
  //   When a directory is in the list, the directory and its content is added
245
  //   in the archive.
246
  //   In this synopsis, the function takes an optional variable list of
247
  //   options. See bellow the supported options.
248
  // Parameters :
249
  //   $p_filelist : An array containing file or directory names, or
250
  //                 a string containing one filename or one directory name, or
251
  //                 a string containing a list of filenames and/or directory
252
  //                 names separated by spaces.
253
  //   $p_add_dir : A path to add before the real path of the archived file,
254
  //                in order to have it memorized in the archive.
255
  //   $p_remove_dir : A path to remove from the real path of the file to archive,
256
  //                   in order to have a shorter path memorized in the archive.
257
  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
258
  //                   is removed first, before $p_add_dir is added.
259
  // Options :
260
  //   PCLZIP_OPT_ADD_PATH :
261
  //   PCLZIP_OPT_REMOVE_PATH :
262
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
263
  //   PCLZIP_OPT_COMMENT :
264
  //   PCLZIP_CB_PRE_ADD :
265
  //   PCLZIP_CB_POST_ADD :
266
  // Return Values :
267
  //   0 on failure,
268
  //   The list of the added files, with a status of the add action.
269
  //   (see PclZip::listContent() for list entry format)
270
  // --------------------------------------------------------------------------------
271
  function create($p_filelist)
272
  {
273
    $v_result=1;
274
275
    // ----- Reset the error handler
276
    $this->privErrorReset();
277
278
    // ----- Set default values
279
    $v_options = array();
280
    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
281
282
    // ----- Look for variable options arguments
283
    $v_size = func_num_args();
284
285
    // ----- Look for arguments
286
    if ($v_size > 1) {
287
      // ----- Get the arguments
288
      $v_arg_list = func_get_args();
289
290
      // ----- Remove from the options list the first argument
291
      array_shift($v_arg_list);
292
      $v_size--;
293
294
      // ----- Look for first arg
295
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
296
297
        // ----- Parse the options
298
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
299
                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
300
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
301
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
302
                                                   PCLZIP_CB_PRE_ADD => 'optional',
303
                                                   PCLZIP_CB_POST_ADD => 'optional',
304
                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
305
                                                   PCLZIP_OPT_COMMENT => 'optional',
306
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
307
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
308
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
309
                                                   //, PCLZIP_OPT_CRYPT => 'optional'
310
                                             ));
311
        if ($v_result != 1) {
312
          return 0;
313
        }
314
      }
315
316
      // ----- Look for 2 args
317
      // Here we need to support the first historic synopsis of the
318
      // method.
319 View Code Duplication
      else {
320
321
        // ----- Get the first argument
322
        $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
323
324
        // ----- Look for the optional second argument
325
        if ($v_size == 2) {
326
          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
327
        }
328
        else if ($v_size > 2) {
329
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
330
		                       "Invalid number / type of arguments");
331
          return 0;
332
        }
333
      }
334
    }
335
    
336
    // ----- Look for default option values
337
    $this->privOptionDefaultThreshold($v_options);
338
339
    // ----- Init
340
    $v_string_list = array();
341
    $v_att_list = array();
342
    $v_filedescr_list = array();
343
    $p_result_list = array();
344
    
345
    // ----- Look if the $p_filelist is really an array
346 View Code Duplication
    if (is_array($p_filelist)) {
347
    
348
      // ----- Look if the first element is also an array
349
      //       This will mean that this is a file description entry
350
      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
351
        $v_att_list = $p_filelist;
352
      }
353
      
354
      // ----- The list is a list of string names
355
      else {
356
        $v_string_list = $p_filelist;
357
      }
358
    }
359
360
    // ----- Look if the $p_filelist is a string
361
    else if (is_string($p_filelist)) {
362
      // ----- Create a list from the string
363
      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
364
    }
365
366
    // ----- Invalid variable type for $p_filelist
367
    else {
368
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
369
      return 0;
370
    }
371
    
372
    // ----- Reformat the string list
373 View Code Duplication
    if (sizeof($v_string_list) != 0) {
374
      foreach ($v_string_list as $v_string) {
375
        if ($v_string != '') {
376
          $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
377
        }
378
        else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
379
        }
380
      }
381
    }
382
    
383
    // ----- For each file in the list check the attributes
384
    $v_supported_attributes
385
    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
386
             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
387
             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
388
             ,PCLZIP_ATT_FILE_MTIME => 'optional'
389
             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
390
             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
391
						);
392 View Code Duplication
    foreach ($v_att_list as $v_entry) {
393
      $v_result = $this->privFileDescrParseAtt($v_entry,
394
                                               $v_filedescr_list[],
395
                                               $v_options,
396
                                               $v_supported_attributes);
397
      if ($v_result != 1) {
398
        return 0;
399
      }
400
    }
401
402
    // ----- Expand the filelist (expand directories)
403
    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
404
    if ($v_result != 1) {
405
      return 0;
406
    }
407
408
    // ----- Call the create fct
409
    $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
410
    if ($v_result != 1) {
411
      return 0;
412
    }
413
414
    // ----- Return
415
    return $p_result_list;
416
  }
417
  // --------------------------------------------------------------------------------
418
419
  // --------------------------------------------------------------------------------
420
  // Function :
421
  //   add($p_filelist, $p_add_dir="", $p_remove_dir="")
422
  //   add($p_filelist, $p_option, $p_option_value, ...)
423
  // Description :
424
  //   This method supports two synopsis. The first one is historical.
425
  //   This methods add the list of files in an existing archive.
426
  //   If a file with the same name already exists, it is added at the end of the
427
  //   archive, the first one is still present.
428
  //   If the archive does not exist, it is created.
429
  // Parameters :
430
  //   $p_filelist : An array containing file or directory names, or
431
  //                 a string containing one filename or one directory name, or
432
  //                 a string containing a list of filenames and/or directory
433
  //                 names separated by spaces.
434
  //   $p_add_dir : A path to add before the real path of the archived file,
435
  //                in order to have it memorized in the archive.
436
  //   $p_remove_dir : A path to remove from the real path of the file to archive,
437
  //                   in order to have a shorter path memorized in the archive.
438
  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
439
  //                   is removed first, before $p_add_dir is added.
440
  // Options :
441
  //   PCLZIP_OPT_ADD_PATH :
442
  //   PCLZIP_OPT_REMOVE_PATH :
443
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
444
  //   PCLZIP_OPT_COMMENT :
445
  //   PCLZIP_OPT_ADD_COMMENT :
446
  //   PCLZIP_OPT_PREPEND_COMMENT :
447
  //   PCLZIP_CB_PRE_ADD :
448
  //   PCLZIP_CB_POST_ADD :
449
  // Return Values :
450
  //   0 on failure,
451
  //   The list of the added files, with a status of the add action.
452
  //   (see PclZip::listContent() for list entry format)
453
  // --------------------------------------------------------------------------------
454
  function add($p_filelist)
455
  {
456
    $v_result=1;
457
458
    // ----- Reset the error handler
459
    $this->privErrorReset();
460
461
    // ----- Set default values
462
    $v_options = array();
463
    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
464
465
    // ----- Look for variable options arguments
466
    $v_size = func_num_args();
467
468
    // ----- Look for arguments
469
    if ($v_size > 1) {
470
      // ----- Get the arguments
471
      $v_arg_list = func_get_args();
472
473
      // ----- Remove form the options list the first argument
474
      array_shift($v_arg_list);
475
      $v_size--;
476
477
      // ----- Look for first arg
478
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
479
480
        // ----- Parse the options
481
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
482
                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
483
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
484
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
485
                                                   PCLZIP_CB_PRE_ADD => 'optional',
486
                                                   PCLZIP_CB_POST_ADD => 'optional',
487
                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
488
                                                   PCLZIP_OPT_COMMENT => 'optional',
489
                                                   PCLZIP_OPT_ADD_COMMENT => 'optional',
490
                                                   PCLZIP_OPT_PREPEND_COMMENT => 'optional',
491
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
492
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
493
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
494
                                                   //, PCLZIP_OPT_CRYPT => 'optional'
495
												   ));
496
        if ($v_result != 1) {
497
          return 0;
498
        }
499
      }
500
501
      // ----- Look for 2 args
502
      // Here we need to support the first historic synopsis of the
503
      // method.
504 View Code Duplication
      else {
505
506
        // ----- Get the first argument
507
        $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
508
509
        // ----- Look for the optional second argument
510
        if ($v_size == 2) {
511
          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
512
        }
513
        else if ($v_size > 2) {
514
          // ----- Error log
515
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
516
517
          // ----- Return
518
          return 0;
519
        }
520
      }
521
    }
522
523
    // ----- Look for default option values
524
    $this->privOptionDefaultThreshold($v_options);
525
526
    // ----- Init
527
    $v_string_list = array();
528
    $v_att_list = array();
529
    $v_filedescr_list = array();
530
    $p_result_list = array();
531
    
532
    // ----- Look if the $p_filelist is really an array
533 View Code Duplication
    if (is_array($p_filelist)) {
534
    
535
      // ----- Look if the first element is also an array
536
      //       This will mean that this is a file description entry
537
      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
538
        $v_att_list = $p_filelist;
539
      }
540
      
541
      // ----- The list is a list of string names
542
      else {
543
        $v_string_list = $p_filelist;
544
      }
545
    }
546
547
    // ----- Look if the $p_filelist is a string
548
    else if (is_string($p_filelist)) {
549
      // ----- Create a list from the string
550
      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
551
    }
552
553
    // ----- Invalid variable type for $p_filelist
554
    else {
555
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
556
      return 0;
557
    }
558
    
559
    // ----- Reformat the string list
560 View Code Duplication
    if (sizeof($v_string_list) != 0) {
561
      foreach ($v_string_list as $v_string) {
562
        $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
563
      }
564
    }
565
    
566
    // ----- For each file in the list check the attributes
567
    $v_supported_attributes
568
    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
569
             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
570
             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
571
             ,PCLZIP_ATT_FILE_MTIME => 'optional'
572
             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
573
             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
574
						);
575 View Code Duplication
    foreach ($v_att_list as $v_entry) {
576
      $v_result = $this->privFileDescrParseAtt($v_entry,
577
                                               $v_filedescr_list[],
578
                                               $v_options,
579
                                               $v_supported_attributes);
580
      if ($v_result != 1) {
581
        return 0;
582
      }
583
    }
584
585
    // ----- Expand the filelist (expand directories)
586
    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
587
    if ($v_result != 1) {
588
      return 0;
589
    }
590
591
    // ----- Call the create fct
592
    $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
593
    if ($v_result != 1) {
594
      return 0;
595
    }
596
597
    // ----- Return
598
    return $p_result_list;
599
  }
600
  // --------------------------------------------------------------------------------
601
602
  // --------------------------------------------------------------------------------
603
  // Function : listContent()
604
  // Description :
605
  //   This public method, gives the list of the files and directories, with their
606
  //   properties.
607
  //   The properties of each entries in the list are (used also in other functions) :
608
  //     filename : Name of the file. For a create or add action it is the filename
609
  //                given by the user. For an extract function it is the filename
610
  //                of the extracted file.
611
  //     stored_filename : Name of the file / directory stored in the archive.
612
  //     size : Size of the stored file.
613
  //     compressed_size : Size of the file's data compressed in the archive
614
  //                       (without the headers overhead)
615
  //     mtime : Last known modification date of the file (UNIX timestamp)
616
  //     comment : Comment associated with the file
617
  //     folder : true | false
618
  //     index : index of the file in the archive
619
  //     status : status of the action (depending of the action) :
620
  //              Values are :
621
  //                ok : OK !
622
  //                filtered : the file / dir is not extracted (filtered by user)
623
  //                already_a_directory : the file can not be extracted because a
624
  //                                      directory with the same name already exists
625
  //                write_protected : the file can not be extracted because a file
626
  //                                  with the same name already exists and is
627
  //                                  write protected
628
  //                newer_exist : the file was not extracted because a newer file exists
629
  //                path_creation_fail : the file is not extracted because the folder
630
  //                                     does not exist and can not be created
631
  //                write_error : the file was not extracted because there was a
632
  //                              error while writing the file
633
  //                read_error : the file was not extracted because there was a error
634
  //                             while reading the file
635
  //                invalid_header : the file was not extracted because of an archive
636
  //                                 format error (bad file header)
637
  //   Note that each time a method can continue operating when there
638
  //   is an action error on a file, the error is only logged in the file status.
639
  // Return Values :
640
  //   0 on an unrecoverable failure,
641
  //   The list of the files in the archive.
642
  // --------------------------------------------------------------------------------
643
  function listContent()
644
  {
645
    $v_result=1;
646
647
    // ----- Reset the error handler
648
    $this->privErrorReset();
649
650
    // ----- Check archive
651
    if (!$this->privCheckFormat()) {
652
      return(0);
653
    }
654
655
    // ----- Call the extracting fct
656
    $p_list = array();
657
    if (($v_result = $this->privList($p_list)) != 1)
658
    {
659
      unset($p_list);
660
      return(0);
661
    }
662
663
    // ----- Return
664
    return $p_list;
665
  }
666
  // --------------------------------------------------------------------------------
667
668
  // --------------------------------------------------------------------------------
669
  // Function :
670
  //   extract($p_path="./", $p_remove_path="")
671
  //   extract([$p_option, $p_option_value, ...])
672
  // Description :
673
  //   This method supports two synopsis. The first one is historical.
674
  //   This method extract all the files / directories from the archive to the
675
  //   folder indicated in $p_path.
676
  //   If you want to ignore the 'root' part of path of the memorized files
677
  //   you can indicate this in the optional $p_remove_path parameter.
678
  //   By default, if a newer file with the same name already exists, the
679
  //   file is not extracted.
680
  //
681
  //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
682
  //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
683
  //   at the end of the path value of PCLZIP_OPT_PATH.
684
  // Parameters :
685
  //   $p_path : Path where the files and directories are to be extracted
686
  //   $p_remove_path : First part ('root' part) of the memorized path
687
  //                    (if any similar) to remove while extracting.
688
  // Options :
689
  //   PCLZIP_OPT_PATH :
690
  //   PCLZIP_OPT_ADD_PATH :
691
  //   PCLZIP_OPT_REMOVE_PATH :
692
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
693
  //   PCLZIP_CB_PRE_EXTRACT :
694
  //   PCLZIP_CB_POST_EXTRACT :
695
  // Return Values :
696
  //   0 or a negative value on failure,
697
  //   The list of the extracted files, with a status of the action.
698
  //   (see PclZip::listContent() for list entry format)
699
  // --------------------------------------------------------------------------------
700
  function extract()
701
  {
702
    $v_result=1;
703
704
    // ----- Reset the error handler
705
    $this->privErrorReset();
706
707
    // ----- Check archive
708
    if (!$this->privCheckFormat()) {
709
      return(0);
710
    }
711
712
    // ----- Set default values
713
    $v_options = array();
714
//    $v_path = "./";
715
    $v_path = '';
716
    $v_remove_path = "";
717
    $v_remove_all_path = false;
718
719
    // ----- Look for variable options arguments
720
    $v_size = func_num_args();
721
722
    // ----- Default values for option
723
    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
724
725
    // ----- Look for arguments
726
    if ($v_size > 0) {
727
      // ----- Get the arguments
728
      $v_arg_list = func_get_args();
729
730
      // ----- Look for first arg
731
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
732
733
        // ----- Parse the options
734
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
735
                                            array (PCLZIP_OPT_PATH => 'optional',
736
                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
737
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
738
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
739
                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
740
                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
741
                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
742
                                                   PCLZIP_OPT_BY_NAME => 'optional',
743
                                                   PCLZIP_OPT_BY_EREG => 'optional',
744
                                                   PCLZIP_OPT_BY_PREG => 'optional',
745
                                                   PCLZIP_OPT_BY_INDEX => 'optional',
746
                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
747
                                                   PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
748
                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
749
                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
750
                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
751
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
752
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
753
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
754
												    ));
755
        if ($v_result != 1) {
756
          return 0;
757
        }
758
759
        // ----- Set the arguments
760
        if (isset($v_options[PCLZIP_OPT_PATH])) {
761
          $v_path = $v_options[PCLZIP_OPT_PATH];
762
        }
763
        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
764
          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
765
        }
766
        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
767
          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
768
        }
769 View Code Duplication
        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
770
          // ----- Check for '/' in last path char
771
          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
772
            $v_path .= '/';
773
          }
774
          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
775
        }
776
      }
777
778
      // ----- Look for 2 args
779
      // Here we need to support the first historic synopsis of the
780
      // method.
781
      else {
782
783
        // ----- Get the first argument
784
        $v_path = $v_arg_list[0];
785
786
        // ----- Look for the optional second argument
787
        if ($v_size == 2) {
788
          $v_remove_path = $v_arg_list[1];
789
        }
790
        else if ($v_size > 2) {
791
          // ----- Error log
792
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
793
794
          // ----- Return
795
          return 0;
796
        }
797
      }
798
    }
799
800
    // ----- Look for default option values
801
    $this->privOptionDefaultThreshold($v_options);
802
803
    // ----- Trace
804
805
    // ----- Call the extracting fct
806
    $p_list = array();
807
    $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
808
	                                     $v_remove_all_path, $v_options);
809
    if ($v_result < 1) {
810
      unset($p_list);
811
      return(0);
812
    }
813
814
    // ----- Return
815
    return $p_list;
816
  }
817
  // --------------------------------------------------------------------------------
818
819
820
  // --------------------------------------------------------------------------------
821
  // Function :
822
  //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
823
  //   extractByIndex($p_index, [$p_option, $p_option_value, ...])
824
  // Description :
825
  //   This method supports two synopsis. The first one is historical.
826
  //   This method is doing a partial extract of the archive.
827
  //   The extracted files or folders are identified by their index in the
828
  //   archive (from 0 to n).
829
  //   Note that if the index identify a folder, only the folder entry is
830
  //   extracted, not all the files included in the archive.
831
  // Parameters :
832
  //   $p_index : A single index (integer) or a string of indexes of files to
833
  //              extract. The form of the string is "0,4-6,8-12" with only numbers
834
  //              and '-' for range or ',' to separate ranges. No spaces or ';'
835
  //              are allowed.
836
  //   $p_path : Path where the files and directories are to be extracted
837
  //   $p_remove_path : First part ('root' part) of the memorized path
838
  //                    (if any similar) to remove while extracting.
839
  // Options :
840
  //   PCLZIP_OPT_PATH :
841
  //   PCLZIP_OPT_ADD_PATH :
842
  //   PCLZIP_OPT_REMOVE_PATH :
843
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
844
  //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
845
  //     not as files.
846
  //     The resulting content is in a new field 'content' in the file
847
  //     structure.
848
  //     This option must be used alone (any other options are ignored).
849
  //   PCLZIP_CB_PRE_EXTRACT :
850
  //   PCLZIP_CB_POST_EXTRACT :
851
  // Return Values :
852
  //   0 on failure,
853
  //   The list of the extracted files, with a status of the action.
854
  //   (see PclZip::listContent() for list entry format)
855
  // --------------------------------------------------------------------------------
856
  //function extractByIndex($p_index, options...)
857
  function extractByIndex($p_index)
858
  {
859
    $v_result=1;
860
861
    // ----- Reset the error handler
862
    $this->privErrorReset();
863
864
    // ----- Check archive
865
    if (!$this->privCheckFormat()) {
866
      return(0);
867
    }
868
869
    // ----- Set default values
870
    $v_options = array();
871
//    $v_path = "./";
872
    $v_path = '';
873
    $v_remove_path = "";
874
    $v_remove_all_path = false;
875
876
    // ----- Look for variable options arguments
877
    $v_size = func_num_args();
878
879
    // ----- Default values for option
880
    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
881
882
    // ----- Look for arguments
883
    if ($v_size > 1) {
884
      // ----- Get the arguments
885
      $v_arg_list = func_get_args();
886
887
      // ----- Remove form the options list the first argument
888
      array_shift($v_arg_list);
889
      $v_size--;
890
891
      // ----- Look for first arg
892
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
893
894
        // ----- Parse the options
895
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
896
                                            array (PCLZIP_OPT_PATH => 'optional',
897
                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
898
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
899
                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
900
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
901
                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
902
                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
903
                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
904
                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
905
                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
906
                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
907
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
908
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
909
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
910
												   ));
911
        if ($v_result != 1) {
912
          return 0;
913
        }
914
915
        // ----- Set the arguments
916
        if (isset($v_options[PCLZIP_OPT_PATH])) {
917
          $v_path = $v_options[PCLZIP_OPT_PATH];
918
        }
919
        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
920
          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
921
        }
922
        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
923
          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
924
        }
925 View Code Duplication
        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
926
          // ----- Check for '/' in last path char
927
          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
928
            $v_path .= '/';
929
          }
930
          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
931
        }
932
        if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
933
          $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
934
        }
935
        else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
936
        }
937
      }
938
939
      // ----- Look for 2 args
940
      // Here we need to support the first historic synopsis of the
941
      // method.
942
      else {
943
944
        // ----- Get the first argument
945
        $v_path = $v_arg_list[0];
946
947
        // ----- Look for the optional second argument
948
        if ($v_size == 2) {
949
          $v_remove_path = $v_arg_list[1];
950
        }
951
        else if ($v_size > 2) {
952
          // ----- Error log
953
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
954
955
          // ----- Return
956
          return 0;
957
        }
958
      }
959
    }
960
961
    // ----- Trace
962
963
    // ----- Trick
964
    // Here I want to reuse extractByRule(), so I need to parse the $p_index
965
    // with privParseOptions()
966
    $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
967
    $v_options_trick = array();
968
    $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
969
                                        array (PCLZIP_OPT_BY_INDEX => 'optional' ));
970
    if ($v_result != 1) {
971
        return 0;
972
    }
973
    $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
974
975
    // ----- Look for default option values
976
    $this->privOptionDefaultThreshold($v_options);
977
978
    // ----- Call the extracting fct
979
    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
980
        return(0);
981
    }
982
983
    // ----- Return
984
    return $p_list;
985
  }
986
  // --------------------------------------------------------------------------------
987
988
  // --------------------------------------------------------------------------------
989
  // Function :
990
  //   delete([$p_option, $p_option_value, ...])
991
  // Description :
992
  //   This method removes files from the archive.
993
  //   If no parameters are given, then all the archive is emptied.
994
  // Parameters :
995
  //   None or optional arguments.
996
  // Options :
997
  //   PCLZIP_OPT_BY_INDEX :
998
  //   PCLZIP_OPT_BY_NAME :
999
  //   PCLZIP_OPT_BY_EREG : 
1000
  //   PCLZIP_OPT_BY_PREG :
1001
  // Return Values :
1002
  //   0 on failure,
1003
  //   The list of the files which are still present in the archive.
1004
  //   (see PclZip::listContent() for list entry format)
1005
  // --------------------------------------------------------------------------------
1006
  function delete()
1007
  {
1008
    $v_result=1;
1009
1010
    // ----- Reset the error handler
1011
    $this->privErrorReset();
1012
1013
    // ----- Check archive
1014
    if (!$this->privCheckFormat()) {
1015
      return(0);
1016
    }
1017
1018
    // ----- Set default values
1019
    $v_options = array();
1020
1021
    // ----- Look for variable options arguments
1022
    $v_size = func_num_args();
1023
1024
    // ----- Look for arguments
1025
    if ($v_size > 0) {
1026
      // ----- Get the arguments
1027
      $v_arg_list = func_get_args();
1028
1029
      // ----- Parse the options
1030
      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1031
                                        array (PCLZIP_OPT_BY_NAME => 'optional',
1032
                                               PCLZIP_OPT_BY_EREG => 'optional',
1033
                                               PCLZIP_OPT_BY_PREG => 'optional',
1034
                                               PCLZIP_OPT_BY_INDEX => 'optional' ));
1035
      if ($v_result != 1) {
1036
          return 0;
1037
      }
1038
    }
1039
1040
    // ----- Magic quotes trick
1041
    $this->privDisableMagicQuotes();
1042
1043
    // ----- Call the delete fct
1044
    $v_list = array();
1045
    if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1046
      $this->privSwapBackMagicQuotes();
1047
      unset($v_list);
1048
      return(0);
1049
    }
1050
1051
    // ----- Magic quotes trick
1052
    $this->privSwapBackMagicQuotes();
1053
1054
    // ----- Return
1055
    return $v_list;
1056
  }
1057
  // --------------------------------------------------------------------------------
1058
1059
  // --------------------------------------------------------------------------------
1060
  // Function : deleteByIndex()
1061
  // Description :
1062
  //   ***** Deprecated *****
1063
  //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1064
  // --------------------------------------------------------------------------------
1065
  function deleteByIndex($p_index)
1066
  {
1067
    
1068
    $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1069
1070
    // ----- Return
1071
    return $p_list;
1072
  }
1073
  // --------------------------------------------------------------------------------
1074
1075
  // --------------------------------------------------------------------------------
1076
  // Function : properties()
1077
  // Description :
1078
  //   This method gives the properties of the archive.
1079
  //   The properties are :
1080
  //     nb : Number of files in the archive
1081
  //     comment : Comment associated with the archive file
1082
  //     status : not_exist, ok
1083
  // Parameters :
1084
  //   None
1085
  // Return Values :
1086
  //   0 on failure,
1087
  //   An array with the archive properties.
1088
  // --------------------------------------------------------------------------------
1089
  function properties()
1090
  {
1091
1092
    // ----- Reset the error handler
1093
    $this->privErrorReset();
1094
1095
    // ----- Magic quotes trick
1096
    $this->privDisableMagicQuotes();
1097
1098
    // ----- Check archive
1099
    if (!$this->privCheckFormat()) {
1100
      $this->privSwapBackMagicQuotes();
1101
      return(0);
1102
    }
1103
1104
    // ----- Default properties
1105
    $v_prop = array();
1106
    $v_prop['comment'] = '';
1107
    $v_prop['nb'] = 0;
1108
    $v_prop['status'] = 'not_exist';
1109
1110
    // ----- Look if file exists
1111
    if (@is_file($this->zipname))
1112
    {
1113
      // ----- Open the zip file
1114 View Code Duplication
      if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1115
      {
1116
        $this->privSwapBackMagicQuotes();
1117
        
1118
        // ----- Error log
1119
        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1120
1121
        // ----- Return
1122
        return 0;
1123
      }
1124
1125
      // ----- Read the central directory informations
1126
      $v_central_dir = array();
1127
      if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1128
      {
1129
        $this->privSwapBackMagicQuotes();
1130
        return 0;
1131
      }
1132
1133
      // ----- Close the zip file
1134
      $this->privCloseFd();
1135
1136
      // ----- Set the user attributes
1137
      $v_prop['comment'] = $v_central_dir['comment'];
1138
      $v_prop['nb'] = $v_central_dir['entries'];
1139
      $v_prop['status'] = 'ok';
1140
    }
1141
1142
    // ----- Magic quotes trick
1143
    $this->privSwapBackMagicQuotes();
1144
1145
    // ----- Return
1146
    return $v_prop;
1147
  }
1148
  // --------------------------------------------------------------------------------
1149
1150
  // --------------------------------------------------------------------------------
1151
  // Function : duplicate()
1152
  // Description :
1153
  //   This method creates an archive by copying the content of an other one. If
1154
  //   the archive already exist, it is replaced by the new one without any warning.
1155
  // Parameters :
1156
  //   $p_archive : The filename of a valid archive, or
1157
  //                a valid PclZip object.
1158
  // Return Values :
1159
  //   1 on success.
1160
  //   0 or a negative value on error (error code).
1161
  // --------------------------------------------------------------------------------
1162
  function duplicate($p_archive)
1163
  {
1164
    $v_result = 1;
1165
1166
    // ----- Reset the error handler
1167
    $this->privErrorReset();
1168
1169
    // ----- Look if the $p_archive is a PclZip object
1170
    if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1171
    {
1172
1173
      // ----- Duplicate the archive
1174
      $v_result = $this->privDuplicate($p_archive->zipname);
1175
    }
1176
1177
    // ----- Look if the $p_archive is a string (so a filename)
1178
    else if (is_string($p_archive))
1179
    {
1180
1181
      // ----- Check that $p_archive is a valid zip file
1182
      // TBC : Should also check the archive format
1183
      if (!is_file($p_archive)) {
1184
        // ----- Error log
1185
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1186
        $v_result = PCLZIP_ERR_MISSING_FILE;
1187
      }
1188
      else {
1189
        // ----- Duplicate the archive
1190
        $v_result = $this->privDuplicate($p_archive);
1191
      }
1192
    }
1193
1194
    // ----- Invalid variable
1195
    else
1196
    {
1197
      // ----- Error log
1198
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1199
      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1200
    }
1201
1202
    // ----- Return
1203
    return $v_result;
1204
  }
1205
  // --------------------------------------------------------------------------------
1206
1207
  // --------------------------------------------------------------------------------
1208
  // Function : merge()
1209
  // Description :
1210
  //   This method merge the $p_archive_to_add archive at the end of the current
1211
  //   one ($this).
1212
  //   If the archive ($this) does not exist, the merge becomes a duplicate.
1213
  //   If the $p_archive_to_add archive does not exist, the merge is a success.
1214
  // Parameters :
1215
  //   $p_archive_to_add : It can be directly the filename of a valid zip archive,
1216
  //                       or a PclZip object archive.
1217
  // Return Values :
1218
  //   1 on success,
1219
  //   0 or negative values on error (see below).
1220
  // --------------------------------------------------------------------------------
1221
  function merge($p_archive_to_add)
1222
  {
1223
    $v_result = 1;
1224
1225
    // ----- Reset the error handler
1226
    $this->privErrorReset();
1227
1228
    // ----- Check archive
1229
    if (!$this->privCheckFormat()) {
1230
      return(0);
1231
    }
1232
1233
    // ----- Look if the $p_archive_to_add is a PclZip object
1234
    if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1235
    {
1236
1237
      // ----- Merge the archive
1238
      $v_result = $this->privMerge($p_archive_to_add);
1239
    }
1240
1241
    // ----- Look if the $p_archive_to_add is a string (so a filename)
1242
    else if (is_string($p_archive_to_add))
1243
    {
1244
1245
      // ----- Create a temporary archive
1246
      $v_object_archive = new PclZip($p_archive_to_add);
1247
1248
      // ----- Merge the archive
1249
      $v_result = $this->privMerge($v_object_archive);
1250
    }
1251
1252
    // ----- Invalid variable
1253
    else
1254
    {
1255
      // ----- Error log
1256
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1257
      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1258
    }
1259
1260
    // ----- Return
1261
    return $v_result;
1262
  }
1263
  // --------------------------------------------------------------------------------
1264
1265
1266
1267
  // --------------------------------------------------------------------------------
1268
  // Function : errorCode()
1269
  // Description :
1270
  // Parameters :
1271
  // --------------------------------------------------------------------------------
1272
  function errorCode()
1273
  {
1274
    if (PCLZIP_ERROR_EXTERNAL == 1) {
1275
      return(PclErrorCode());
1276
    }
1277
    else {
1278
      return($this->error_code);
1279
    }
1280
  }
1281
  // --------------------------------------------------------------------------------
1282
1283
  // --------------------------------------------------------------------------------
1284
  // Function : errorName()
1285
  // Description :
1286
  // Parameters :
1287
  // --------------------------------------------------------------------------------
1288
  function errorName($p_with_code=false)
1289
  {
1290
    $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1291
                      PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1292
                      PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1293
                      PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1294
                      PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1295
                      PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1296
                      PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1297
                      PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1298
                      PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1299
                      PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1300
                      PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1301
                      PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1302
                      PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1303
                      PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1304
                      PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1305
                      PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1306
                      PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1307
                      PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1308
                      PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1309
                      ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1310
                      ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1311
                    );
1312
1313
    if (isset($v_name[$this->error_code])) {
1314
      $v_value = $v_name[$this->error_code];
1315
    }
1316
    else {
1317
      $v_value = 'NoName';
1318
    }
1319
1320
    if ($p_with_code) {
1321
      return($v_value.' ('.$this->error_code.')');
1322
    }
1323
    else {
1324
      return($v_value);
1325
    }
1326
  }
1327
  // --------------------------------------------------------------------------------
1328
1329
  // --------------------------------------------------------------------------------
1330
  // Function : errorInfo()
1331
  // Description :
1332
  // Parameters :
1333
  // --------------------------------------------------------------------------------
1334
  function errorInfo($p_full=false)
1335
  {
1336
    if (PCLZIP_ERROR_EXTERNAL == 1) {
1337
      return(PclErrorString());
1338
    }
1339
    else {
1340
      if ($p_full) {
1341
        return($this->errorName(true)." : ".$this->error_string);
1342
      }
1343
      else {
1344
        return($this->error_string." [code ".$this->error_code."]");
1345
      }
1346
    }
1347
  }
1348
  // --------------------------------------------------------------------------------
1349
1350
1351
// --------------------------------------------------------------------------------
1352
// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1353
// *****                                                        *****
1354
// *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
1355
// --------------------------------------------------------------------------------
1356
1357
1358
1359
  // --------------------------------------------------------------------------------
1360
  // Function : privCheckFormat()
1361
  // Description :
1362
  //   This method check that the archive exists and is a valid zip archive.
1363
  //   Several level of check exists. (futur)
1364
  // Parameters :
1365
  //   $p_level : Level of check. Default 0.
1366
  //              0 : Check the first bytes (magic codes) (default value))
1367
  //              1 : 0 + Check the central directory (futur)
1368
  //              2 : 1 + Check each file header (futur)
1369
  // Return Values :
1370
  //   true on success,
1371
  //   false on error, the error code is set.
1372
  // --------------------------------------------------------------------------------
1373
  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...
1374
  {
1375
    $v_result = true;
1376
1377
	// ----- Reset the file system cache
1378
    clearstatcache();
1379
1380
    // ----- Reset the error handler
1381
    $this->privErrorReset();
1382
1383
    // ----- Look if the file exits
1384
    if (!is_file($this->zipname)) {
1385
      // ----- Error log
1386
      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1387
      return(false);
1388
    }
1389
1390
    // ----- Check that the file is readeable
1391
    if (!is_readable($this->zipname)) {
1392
      // ----- Error log
1393
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1394
      return(false);
1395
    }
1396
1397
    // ----- Check the magic code
1398
    // TBC
1399
1400
    // ----- Check the central header
1401
    // TBC
1402
1403
    // ----- Check each file header
1404
    // TBC
1405
1406
    // ----- Return
1407
    return $v_result;
1408
  }
1409
  // --------------------------------------------------------------------------------
1410
1411
  // --------------------------------------------------------------------------------
1412
  // Function : privParseOptions()
1413
  // Description :
1414
  //   This internal methods reads the variable list of arguments ($p_options_list,
1415
  //   $p_size) and generate an array with the options and values ($v_result_list).
1416
  //   $v_requested_options contains the options that can be present and those that
1417
  //   must be present.
1418
  //   $v_requested_options is an array, with the option value as key, and 'optional',
1419
  //   or 'mandatory' as value.
1420
  // Parameters :
1421
  //   See above.
1422
  // Return Values :
1423
  //   1 on success.
1424
  //   0 on failure.
1425
  // --------------------------------------------------------------------------------
1426
  function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1427
  {
1428
    $v_result=1;
1429
    
1430
    // ----- Read the options
1431
    $i=0;
1432
    while ($i<$p_size) {
1433
1434
      // ----- Check if the option is supported
1435 View Code Duplication
      if (!isset($v_requested_options[$p_options_list[$i]])) {
1436
        // ----- Error log
1437
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1438
1439
        // ----- Return
1440
        return PclZip::errorCode();
1441
      }
1442
1443
      // ----- Look for next option
1444
      switch ($p_options_list[$i]) {
1445
        // ----- Look for options that request a path value
1446
        case PCLZIP_OPT_PATH :
1447
        case PCLZIP_OPT_REMOVE_PATH :
1448 View Code Duplication
        case PCLZIP_OPT_ADD_PATH :
1449
          // ----- Check the number of parameters
1450
          if (($i+1) >= $p_size) {
1451
            // ----- Error log
1452
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1453
1454
            // ----- Return
1455
            return PclZip::errorCode();
1456
          }
1457
1458
          // ----- Get the value
1459
          $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1460
          $i++;
1461
        break;
1462
1463
        case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
1464
          // ----- Check the number of parameters
1465
          if (($i+1) >= $p_size) {
1466
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1467
            return PclZip::errorCode();
1468
          }
1469
          
1470
          // ----- Check for incompatible options
1471
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1472
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1473
            return PclZip::errorCode();
1474
          }
1475
          
1476
          // ----- Check the value
1477
          $v_value = $p_options_list[$i+1];
1478
          if ((!is_integer($v_value)) || ($v_value<0)) {
1479
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1480
            return PclZip::errorCode();
1481
          }
1482
1483
          // ----- Get the value (and convert it in bytes)
1484
          $v_result_list[$p_options_list[$i]] = $v_value*1048576;
1485
          $i++;
1486
        break;
1487
1488
        case PCLZIP_OPT_TEMP_FILE_ON :
1489
          // ----- Check for incompatible options
1490
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1491
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1492
            return PclZip::errorCode();
1493
          }
1494
          
1495
          $v_result_list[$p_options_list[$i]] = true;
1496
        break;
1497
1498
        case PCLZIP_OPT_TEMP_FILE_OFF :
1499
          // ----- Check for incompatible options
1500
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1501
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1502
            return PclZip::errorCode();
1503
          }
1504
          // ----- Check for incompatible options
1505
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1506
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1507
            return PclZip::errorCode();
1508
          }
1509
          
1510
          $v_result_list[$p_options_list[$i]] = true;
1511
        break;
1512
1513
        case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1514
          // ----- Check the number of parameters
1515
          if (($i+1) >= $p_size) {
1516
            // ----- Error log
1517
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1518
1519
            // ----- Return
1520
            return PclZip::errorCode();
1521
          }
1522
1523
          // ----- Get the value
1524
          if (   is_string($p_options_list[$i+1])
1525
              && ($p_options_list[$i+1] != '')) {
1526
            $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1527
            $i++;
1528
          }
1529
          else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
1530
          }
1531
        break;
1532
1533
        // ----- Look for options that request an array of string for value
1534
        case PCLZIP_OPT_BY_NAME :
1535
          // ----- Check the number of parameters
1536
          if (($i+1) >= $p_size) {
1537
            // ----- Error log
1538
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1539
1540
            // ----- Return
1541
            return PclZip::errorCode();
1542
          }
1543
1544
          // ----- Get the value
1545
          if (is_string($p_options_list[$i+1])) {
1546
              $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1547
          }
1548
          else if (is_array($p_options_list[$i+1])) {
1549
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1550
          }
1551
          else {
1552
            // ----- Error log
1553
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1554
1555
            // ----- Return
1556
            return PclZip::errorCode();
1557
          }
1558
          $i++;
1559
        break;
1560
1561
        // ----- Look for options that request an EREG or PREG expression
1562
        case PCLZIP_OPT_BY_EREG :
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1563
          // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
1564
          // to PCLZIP_OPT_BY_PREG
1565
          $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1566 View Code Duplication
        case PCLZIP_OPT_BY_PREG :
1567
        //case PCLZIP_OPT_CRYPT :
1568
          // ----- Check the number of parameters
1569
          if (($i+1) >= $p_size) {
1570
            // ----- Error log
1571
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1572
1573
            // ----- Return
1574
            return PclZip::errorCode();
1575
          }
1576
1577
          // ----- Get the value
1578
          if (is_string($p_options_list[$i+1])) {
1579
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1580
          }
1581
          else {
1582
            // ----- Error log
1583
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1584
1585
            // ----- Return
1586
            return PclZip::errorCode();
1587
          }
1588
          $i++;
1589
        break;
1590
1591
        // ----- Look for options that takes a string
1592
        case PCLZIP_OPT_COMMENT :
1593
        case PCLZIP_OPT_ADD_COMMENT :
1594 View Code Duplication
        case PCLZIP_OPT_PREPEND_COMMENT :
1595
          // ----- Check the number of parameters
1596
          if (($i+1) >= $p_size) {
1597
            // ----- Error log
1598
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1599
			                     "Missing parameter value for option '"
1600
								 .PclZipUtilOptionText($p_options_list[$i])
1601
								 ."'");
1602
1603
            // ----- Return
1604
            return PclZip::errorCode();
1605
          }
1606
1607
          // ----- Get the value
1608
          if (is_string($p_options_list[$i+1])) {
1609
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1610
          }
1611
          else {
1612
            // ----- Error log
1613
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1614
			                     "Wrong parameter value for option '"
1615
								 .PclZipUtilOptionText($p_options_list[$i])
1616
								 ."'");
1617
1618
            // ----- Return
1619
            return PclZip::errorCode();
1620
          }
1621
          $i++;
1622
        break;
1623
1624
        // ----- Look for options that request an array of index
1625
        case PCLZIP_OPT_BY_INDEX :
1626
          // ----- Check the number of parameters
1627
          if (($i+1) >= $p_size) {
1628
            // ----- Error log
1629
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1630
1631
            // ----- Return
1632
            return PclZip::errorCode();
1633
          }
1634
1635
          // ----- Get the value
1636
          $v_work_list = array();
1637
          if (is_string($p_options_list[$i+1])) {
1638
1639
              // ----- Remove spaces
1640
              $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1641
1642
              // ----- Parse items
1643
              $v_work_list = explode(",", $p_options_list[$i+1]);
1644
          }
1645
          else if (is_integer($p_options_list[$i+1])) {
1646
              $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1647
          }
1648
          else if (is_array($p_options_list[$i+1])) {
1649
              $v_work_list = $p_options_list[$i+1];
1650
          }
1651
          else {
1652
            // ----- Error log
1653
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1654
1655
            // ----- Return
1656
            return PclZip::errorCode();
1657
          }
1658
          
1659
          // ----- Reduce the index list
1660
          // each index item in the list must be a couple with a start and
1661
          // an end value : [0,3], [5-5], [8-10], ...
1662
          // ----- Check the format of each item
1663
          $v_sort_flag=false;
1664
          $v_sort_value=0;
1665
          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...
1666
              // ----- Explode the item
1667
              $v_item_list = explode("-", $v_work_list[$j]);
1668
              $v_size_item_list = sizeof($v_item_list);
1669
              
1670
              // ----- TBC : Here we might check that each item is a
1671
              // real integer ...
1672
              
1673
              // ----- Look for single value
1674
              if ($v_size_item_list == 1) {
1675
                  // ----- Set the option value
1676
                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1677
                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1678
              }
1679
              elseif ($v_size_item_list == 2) {
1680
                  // ----- Set the option value
1681
                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1682
                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1683
              }
1684
              else {
1685
                  // ----- Error log
1686
                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1687
1688
                  // ----- Return
1689
                  return PclZip::errorCode();
1690
              }
1691
1692
1693
              // ----- Look for list sort
1694
              if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1695
                  $v_sort_flag=true;
1696
1697
                  // ----- TBC : An automatic sort should be writen ...
1698
                  // ----- Error log
1699
                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1700
1701
                  // ----- Return
1702
                  return PclZip::errorCode();
1703
              }
1704
              $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1705
          }
1706
          
1707
          // ----- Sort the items
1708
          if ($v_sort_flag) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1709
              // TBC : To Be Completed
1710
          }
1711
1712
          // ----- Next option
1713
          $i++;
1714
        break;
1715
1716
        // ----- Look for options that request no value
1717
        case PCLZIP_OPT_REMOVE_ALL_PATH :
1718
        case PCLZIP_OPT_EXTRACT_AS_STRING :
1719
        case PCLZIP_OPT_NO_COMPRESSION :
1720
        case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1721
        case PCLZIP_OPT_REPLACE_NEWER :
1722
        case PCLZIP_OPT_STOP_ON_ERROR :
1723
          $v_result_list[$p_options_list[$i]] = true;
1724
        break;
1725
1726
        // ----- Look for options that request an octal value
1727 View Code Duplication
        case PCLZIP_OPT_SET_CHMOD :
1728
          // ----- Check the number of parameters
1729
          if (($i+1) >= $p_size) {
1730
            // ----- Error log
1731
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1732
1733
            // ----- Return
1734
            return PclZip::errorCode();
1735
          }
1736
1737
          // ----- Get the value
1738
          $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1739
          $i++;
1740
        break;
1741
1742
        // ----- Look for options that request a call-back
1743
        case PCLZIP_CB_PRE_EXTRACT :
1744
        case PCLZIP_CB_POST_EXTRACT :
1745
        case PCLZIP_CB_PRE_ADD :
1746
        case PCLZIP_CB_POST_ADD :
1747
        /* for futur use
1748
        case PCLZIP_CB_PRE_DELETE :
1749
        case PCLZIP_CB_POST_DELETE :
1750
        case PCLZIP_CB_PRE_LIST :
1751
        case PCLZIP_CB_POST_LIST :
1752
        */
1753
          // ----- Check the number of parameters
1754
          if (($i+1) >= $p_size) {
1755
            // ----- Error log
1756
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1757
1758
            // ----- Return
1759
            return PclZip::errorCode();
1760
          }
1761
1762
          // ----- Get the value
1763
          $v_function_name = $p_options_list[$i+1];
1764
1765
          // ----- Check that the value is a valid existing function
1766
          if (!function_exists($v_function_name)) {
1767
            // ----- Error log
1768
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1769
1770
            // ----- Return
1771
            return PclZip::errorCode();
1772
          }
1773
1774
          // ----- Set the attribute
1775
          $v_result_list[$p_options_list[$i]] = $v_function_name;
1776
          $i++;
1777
        break;
1778
1779
        default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1780
          // ----- Error log
1781
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1782
		                       "Unknown parameter '"
1783
							   .$p_options_list[$i]."'");
1784
1785
          // ----- Return
1786
          return PclZip::errorCode();
1787
      }
1788
1789
      // ----- Next options
1790
      $i++;
1791
    }
1792
1793
    // ----- Look for mandatory options
1794 View Code Duplication
    if ($v_requested_options !== false) {
1795
      for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1796
        // ----- Look for mandatory option
1797
        if ($v_requested_options[$key] == 'mandatory') {
1798
          // ----- Look if present
1799
          if (!isset($v_result_list[$key])) {
1800
            // ----- Error log
1801
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1802
1803
            // ----- Return
1804
            return PclZip::errorCode();
1805
          }
1806
        }
1807
      }
1808
    }
1809
    
1810
    // ----- Look for default values
1811
    if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1812
      
1813
    }
1814
1815
    // ----- Return
1816
    return $v_result;
1817
  }
1818
  // --------------------------------------------------------------------------------
1819
1820
  // --------------------------------------------------------------------------------
1821
  // Function : privOptionDefaultThreshold()
1822
  // Description :
1823
  // Parameters :
1824
  // Return Values :
1825
  // --------------------------------------------------------------------------------
1826
  function privOptionDefaultThreshold(&$p_options)
1827
  {
1828
    $v_result=1;
1829
    
1830
    if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1831
        || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1832
      return $v_result;
1833
    }
1834
    
1835
    // ----- Get 'memory_limit' configuration value
1836
    $v_memory_limit = ini_get('memory_limit');
1837
    $v_memory_limit = trim($v_memory_limit);
1838
    $last = strtolower(substr($v_memory_limit, -1));
1839
 
1840
    if($last == 'g')
1841
        //$v_memory_limit = $v_memory_limit*1024*1024*1024;
1842
        $v_memory_limit = $v_memory_limit*1073741824;
1843
    if($last == 'm')
1844
        //$v_memory_limit = $v_memory_limit*1024*1024;
1845
        $v_memory_limit = $v_memory_limit*1048576;
1846
    if($last == 'k')
1847
        $v_memory_limit = $v_memory_limit*1024;
1848
            
1849
    $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
1850
    
1851
1852
    // ----- Sanity check : No threshold if value lower than 1M
1853
    if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1854
      unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1855
    }
1856
          
1857
    // ----- Return
1858
    return $v_result;
1859
  }
1860
  // --------------------------------------------------------------------------------
1861
1862
  // --------------------------------------------------------------------------------
1863
  // Function : privFileDescrParseAtt()
1864
  // Description :
1865
  // Parameters :
1866
  // Return Values :
1867
  //   1 on success.
1868
  //   0 on failure.
1869
  // --------------------------------------------------------------------------------
1870
  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...
1871
  {
1872
    $v_result=1;
1873
    
1874
    // ----- For each file in the list check the attributes
1875
    foreach ($p_file_list as $v_key => $v_value) {
1876
    
1877
      // ----- Check if the option is supported
1878 View Code Duplication
      if (!isset($v_requested_options[$v_key])) {
1879
        // ----- Error log
1880
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1881
1882
        // ----- Return
1883
        return PclZip::errorCode();
1884
      }
1885
1886
      // ----- Look for attribute
1887
      switch ($v_key) {
1888 View Code Duplication
        case PCLZIP_ATT_FILE_NAME :
1889
          if (!is_string($v_value)) {
1890
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1891
            return PclZip::errorCode();
1892
          }
1893
1894
          $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1895
          
1896
          if ($p_filedescr['filename'] == '') {
1897
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1898
            return PclZip::errorCode();
1899
          }
1900
1901
        break;
1902
1903 View Code Duplication
        case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1904
          if (!is_string($v_value)) {
1905
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1906
            return PclZip::errorCode();
1907
          }
1908
1909
          $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1910
1911
          if ($p_filedescr['new_short_name'] == '') {
1912
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1913
            return PclZip::errorCode();
1914
          }
1915
        break;
1916
1917 View Code Duplication
        case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1918
          if (!is_string($v_value)) {
1919
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1920
            return PclZip::errorCode();
1921
          }
1922
1923
          $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1924
1925
          if ($p_filedescr['new_full_name'] == '') {
1926
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1927
            return PclZip::errorCode();
1928
          }
1929
        break;
1930
1931
        // ----- Look for options that takes a string
1932 View Code Duplication
        case PCLZIP_ATT_FILE_COMMENT :
1933
          if (!is_string($v_value)) {
1934
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1935
            return PclZip::errorCode();
1936
          }
1937
1938
          $p_filedescr['comment'] = $v_value;
1939
        break;
1940
1941 View Code Duplication
        case PCLZIP_ATT_FILE_MTIME :
1942
          if (!is_integer($v_value)) {
1943
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1944
            return PclZip::errorCode();
1945
          }
1946
1947
          $p_filedescr['mtime'] = $v_value;
1948
        break;
1949
1950
        case PCLZIP_ATT_FILE_CONTENT :
1951
          $p_filedescr['content'] = $v_value;
1952
        break;
1953
1954
        default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1955
          // ----- Error log
1956
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1957
		                           "Unknown parameter '".$v_key."'");
1958
1959
          // ----- Return
1960
          return PclZip::errorCode();
1961
      }
1962
1963
      // ----- Look for mandatory options
1964 View Code Duplication
      if ($v_requested_options !== false) {
1965
        for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1966
          // ----- Look for mandatory option
1967
          if ($v_requested_options[$key] == 'mandatory') {
1968
            // ----- Look if present
1969
            if (!isset($p_file_list[$key])) {
1970
              PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1971
              return PclZip::errorCode();
1972
            }
1973
          }
1974
        }
1975
      }
1976
    
1977
    // end foreach
1978
    }
1979
    
1980
    // ----- Return
1981
    return $v_result;
1982
  }
1983
  // --------------------------------------------------------------------------------
1984
1985
  // --------------------------------------------------------------------------------
1986
  // Function : privFileDescrExpand()
1987
  // Description :
1988
  //   This method look for each item of the list to see if its a file, a folder
1989
  //   or a string to be added as file. For any other type of files (link, other)
1990
  //   just ignore the item.
1991
  //   Then prepare the information that will be stored for that file.
1992
  //   When its a folder, expand the folder with all the files that are in that 
1993
  //   folder (recursively).
1994
  // Parameters :
1995
  // Return Values :
1996
  //   1 on success.
1997
  //   0 on failure.
1998
  // --------------------------------------------------------------------------------
1999
  function privFileDescrExpand(&$p_filedescr_list, &$p_options)
2000
  {
2001
    $v_result=1;
2002
    
2003
    // ----- Create a result list
2004
    $v_result_list = array();
2005
    
2006
    // ----- Look each entry
2007
    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...
2008
      
2009
      // ----- Get filedescr
2010
      $v_descr = $p_filedescr_list[$i];
2011
      
2012
      // ----- Reduce the filename
2013
      $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
2014
      $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
2015
      
2016
      // ----- Look for real file or folder
2017
      if (file_exists($v_descr['filename'])) {
2018
        if (@is_file($v_descr['filename'])) {
2019
          $v_descr['type'] = 'file';
2020
        }
2021
        else if (@is_dir($v_descr['filename'])) {
2022
          $v_descr['type'] = 'folder';
2023
        }
2024
        else if (@is_link($v_descr['filename'])) {
2025
          // skip
2026
          continue;
2027
        }
2028
        else {
2029
          // skip
2030
          continue;
2031
        }
2032
      }
2033
      
2034
      // ----- Look for string added as file
2035
      else if (isset($v_descr['content'])) {
2036
        $v_descr['type'] = 'virtual_file';
2037
      }
2038
      
2039
      // ----- Missing file
2040
      else {
2041
        // ----- Error log
2042
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
2043
2044
        // ----- Return
2045
        return PclZip::errorCode();
2046
      }
2047
      
2048
      // ----- Calculate the stored filename
2049
      $this->privCalculateStoredFilename($v_descr, $p_options);
2050
      
2051
      // ----- Add the descriptor in result list
2052
      $v_result_list[sizeof($v_result_list)] = $v_descr;
2053
      
2054
      // ----- Look for folder
2055
      if ($v_descr['type'] == 'folder') {
2056
        // ----- List of items in folder
2057
        $v_dirlist_descr = array();
2058
        $v_dirlist_nb = 0;
2059
        if ($v_folder_handler = @opendir($v_descr['filename'])) {
2060
          while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2061
2062
            // ----- Skip '.' and '..'
2063
            if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2064
                continue;
2065
            }
2066
            
2067
            // ----- Compose the full filename
2068
            $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2069
            
2070
            // ----- Look for different stored filename
2071
            // Because the name of the folder was changed, the name of the
2072
            // files/sub-folders also change
2073
            if (($v_descr['stored_filename'] != $v_descr['filename'])
2074
                 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2075
              if ($v_descr['stored_filename'] != '') {
2076
                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2077
              }
2078
              else {
2079
                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2080
              }
2081
            }
2082
      
2083
            $v_dirlist_nb++;
2084
          }
2085
          
2086
          @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...
2087
        }
2088
        else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
2089
          // TBC : unable to open folder in read mode
2090
        }
2091
        
2092
        // ----- Expand each element of the list
2093
        if ($v_dirlist_nb != 0) {
2094
          // ----- Expand
2095
          if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2096
            return $v_result;
2097
          }
2098
          
2099
          // ----- Concat the resulting list
2100
          $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2101
        }
2102
        else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
2103
        }
2104
          
2105
        // ----- Free local array
2106
        unset($v_dirlist_descr);
2107
      }
2108
    }
2109
    
2110
    // ----- Get the result list
2111
    $p_filedescr_list = $v_result_list;
2112
2113
    // ----- Return
2114
    return $v_result;
2115
  }
2116
  // --------------------------------------------------------------------------------
2117
2118
  // --------------------------------------------------------------------------------
2119
  // Function : privCreate()
2120
  // Description :
2121
  // Parameters :
2122
  // Return Values :
2123
  // --------------------------------------------------------------------------------
2124
  function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2125
  {
2126
    $v_result=1;
2127
    $v_list_detail = array();
2128
    
2129
    // ----- Magic quotes trick
2130
    $this->privDisableMagicQuotes();
2131
2132
    // ----- Open the file in write mode
2133
    if (($v_result = $this->privOpenFd('wb')) != 1)
2134
    {
2135
      // ----- Return
2136
      return $v_result;
2137
    }
2138
2139
    // ----- Add the list of files
2140
    $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2141
2142
    // ----- Close
2143
    $this->privCloseFd();
2144
2145
    // ----- Magic quotes trick
2146
    $this->privSwapBackMagicQuotes();
2147
2148
    // ----- Return
2149
    return $v_result;
2150
  }
2151
  // --------------------------------------------------------------------------------
2152
2153
  // --------------------------------------------------------------------------------
2154
  // Function : privAdd()
2155
  // Description :
2156
  // Parameters :
2157
  // Return Values :
2158
  // --------------------------------------------------------------------------------
2159
  function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2160
  {
2161
    $v_result=1;
2162
    $v_list_detail = array();
2163
2164
    // ----- Look if the archive exists or is empty
2165
    if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2166
    {
2167
2168
      // ----- Do a create
2169
      $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2170
2171
      // ----- Return
2172
      return $v_result;
2173
    }
2174
    // ----- Magic quotes trick
2175
    $this->privDisableMagicQuotes();
2176
2177
    // ----- Open the zip file
2178
    if (($v_result=$this->privOpenFd('rb')) != 1)
2179
    {
2180
      // ----- Magic quotes trick
2181
      $this->privSwapBackMagicQuotes();
2182
2183
      // ----- Return
2184
      return $v_result;
2185
    }
2186
2187
    // ----- Read the central directory informations
2188
    $v_central_dir = array();
2189
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2190
    {
2191
      $this->privCloseFd();
2192
      $this->privSwapBackMagicQuotes();
2193
      return $v_result;
2194
    }
2195
2196
    // ----- Go to beginning of File
2197
    @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...
2198
2199
    // ----- Creates a temporay file
2200
    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2201
2202
    // ----- Open the temporary file in write mode
2203
    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2204
    {
2205
      $this->privCloseFd();
2206
      $this->privSwapBackMagicQuotes();
2207
2208
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2209
2210
      // ----- Return
2211
      return PclZip::errorCode();
2212
    }
2213
2214
    // ----- Copy the files from the archive to the temporary file
2215
    // TBC : Here I should better append the file and go back to erase the central dir
2216
    $v_size = $v_central_dir['offset'];
2217
    while ($v_size != 0)
2218
    {
2219
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2220
      $v_buffer = fread($this->zip_fd, $v_read_size);
2221
      @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...
2222
      $v_size -= $v_read_size;
2223
    }
2224
2225
    // ----- Swap the file descriptor
2226
    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2227
    // the following methods on the temporary fil and not the real archive
2228
    $v_swap = $this->zip_fd;
2229
    $this->zip_fd = $v_zip_temp_fd;
2230
    $v_zip_temp_fd = $v_swap;
2231
2232
    // ----- Add the files
2233
    $v_header_list = array();
2234 View Code Duplication
    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2235
    {
2236
      fclose($v_zip_temp_fd);
2237
      $this->privCloseFd();
2238
      @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...
2239
      $this->privSwapBackMagicQuotes();
2240
2241
      // ----- Return
2242
      return $v_result;
2243
    }
2244
2245
    // ----- Store the offset of the central dir
2246
    $v_offset = @ftell($this->zip_fd);
2247
2248
    // ----- Copy the block of file headers from the old archive
2249
    $v_size = $v_central_dir['size'];
2250 View Code Duplication
    while ($v_size != 0)
2251
    {
2252
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2253
      $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2254
      @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...
2255
      $v_size -= $v_read_size;
2256
    }
2257
2258
    // ----- Create the Central Dir files header
2259
    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...
2260
    {
2261
      // ----- Create the file header
2262
      if ($v_header_list[$i]['status'] == 'ok') {
2263 View Code Duplication
        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2264
          fclose($v_zip_temp_fd);
2265
          $this->privCloseFd();
2266
          @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...
2267
          $this->privSwapBackMagicQuotes();
2268
2269
          // ----- Return
2270
          return $v_result;
2271
        }
2272
        $v_count++;
2273
      }
2274
2275
      // ----- Transform the header to a 'usable' info
2276
      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2277
    }
2278
2279
    // ----- Zip file comment
2280
    $v_comment = $v_central_dir['comment'];
2281
    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2282
      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2283
    }
2284
    if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2285
      $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2286
    }
2287
    if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2288
      $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2289
    }
2290
2291
    // ----- Calculate the size of the central header
2292
    $v_size = @ftell($this->zip_fd)-$v_offset;
2293
2294
    // ----- Create the central dir footer
2295
    if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2296
    {
2297
      // ----- Reset the file list
2298
      unset($v_header_list);
2299
      $this->privSwapBackMagicQuotes();
2300
2301
      // ----- Return
2302
      return $v_result;
2303
    }
2304
2305
    // ----- Swap back the file descriptor
2306
    $v_swap = $this->zip_fd;
2307
    $this->zip_fd = $v_zip_temp_fd;
2308
    $v_zip_temp_fd = $v_swap;
2309
2310
    // ----- Close
2311
    $this->privCloseFd();
2312
2313
    // ----- Close the temporary file
2314
    @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...
2315
2316
    // ----- Magic quotes trick
2317
    $this->privSwapBackMagicQuotes();
2318
2319
    // ----- Delete the zip file
2320
    // TBC : I should test the result ...
2321
    @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...
2322
2323
    // ----- Rename the temporary file
2324
    // TBC : I should test the result ...
2325
    //@rename($v_zip_temp_name, $this->zipname);
2326
    PclZipUtilRename($v_zip_temp_name, $this->zipname);
2327
2328
    // ----- Return
2329
    return $v_result;
2330
  }
2331
  // --------------------------------------------------------------------------------
2332
2333
  // --------------------------------------------------------------------------------
2334
  // Function : privOpenFd()
2335
  // Description :
2336
  // Parameters :
2337
  // --------------------------------------------------------------------------------
2338
  function privOpenFd($p_mode)
2339
  {
2340
    $v_result=1;
2341
2342
    // ----- Look if already open
2343
    if ($this->zip_fd != 0)
2344
    {
2345
      // ----- Error log
2346
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2347
2348
      // ----- Return
2349
      return PclZip::errorCode();
2350
    }
2351
2352
    // ----- Open the zip file
2353
    if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2354
    {
2355
      // ----- Error log
2356
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2357
2358
      // ----- Return
2359
      return PclZip::errorCode();
2360
    }
2361
2362
    // ----- Return
2363
    return $v_result;
2364
  }
2365
  // --------------------------------------------------------------------------------
2366
2367
  // --------------------------------------------------------------------------------
2368
  // Function : privCloseFd()
2369
  // Description :
2370
  // Parameters :
2371
  // --------------------------------------------------------------------------------
2372
  function privCloseFd()
2373
  {
2374
    $v_result=1;
2375
2376
    if ($this->zip_fd != 0)
2377
      @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...
2378
    $this->zip_fd = 0;
2379
2380
    // ----- Return
2381
    return $v_result;
2382
  }
2383
  // --------------------------------------------------------------------------------
2384
2385
  // --------------------------------------------------------------------------------
2386
  // Function : privAddList()
2387
  // Description :
2388
  //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2389
  //   different from the real path of the file. This is usefull if you want to have PclTar
2390
  //   running in any directory, and memorize relative path from an other directory.
2391
  // Parameters :
2392
  //   $p_list : An array containing the file or directory names to add in the tar
2393
  //   $p_result_list : list of added files with their properties (specially the status field)
2394
  //   $p_add_dir : Path to add in the filename path archived
2395
  //   $p_remove_dir : Path to remove in the filename path archived
2396
  // Return Values :
2397
  // --------------------------------------------------------------------------------
2398
//  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2399
  function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2400
  {
2401
    $v_result=1;
2402
2403
    // ----- Add the files
2404
    $v_header_list = array();
2405
    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2406
    {
2407
      // ----- Return
2408
      return $v_result;
2409
    }
2410
2411
    // ----- Store the offset of the central dir
2412
    $v_offset = @ftell($this->zip_fd);
2413
2414
    // ----- Create the Central Dir files header
2415
    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...
2416
    {
2417
      // ----- Create the file header
2418
      if ($v_header_list[$i]['status'] == 'ok') {
2419
        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2420
          // ----- Return
2421
          return $v_result;
2422
        }
2423
        $v_count++;
2424
      }
2425
2426
      // ----- Transform the header to a 'usable' info
2427
      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2428
    }
2429
2430
    // ----- Zip file comment
2431
    $v_comment = '';
2432
    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2433
      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2434
    }
2435
2436
    // ----- Calculate the size of the central header
2437
    $v_size = @ftell($this->zip_fd)-$v_offset;
2438
2439
    // ----- Create the central dir footer
2440
    if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2441
    {
2442
      // ----- Reset the file list
2443
      unset($v_header_list);
2444
2445
      // ----- Return
2446
      return $v_result;
2447
    }
2448
2449
    // ----- Return
2450
    return $v_result;
2451
  }
2452
  // --------------------------------------------------------------------------------
2453
2454
  // --------------------------------------------------------------------------------
2455
  // Function : privAddFileList()
2456
  // Description :
2457
  // Parameters :
2458
  //   $p_filedescr_list : An array containing the file description 
2459
  //                      or directory names to add in the zip
2460
  //   $p_result_list : list of added files with their properties (specially the status field)
2461
  // Return Values :
2462
  // --------------------------------------------------------------------------------
2463
  function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2464
  {
2465
    $v_result=1;
2466
    $v_header = array();
2467
2468
    // ----- Recuperate the current number of elt in list
2469
    $v_nb = sizeof($p_result_list);
2470
2471
    // ----- Loop on the files
2472
    for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2473
      // ----- Format the filename
2474
      $p_filedescr_list[$j]['filename']
2475
      = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2476
      
2477
2478
      // ----- Skip empty file names
2479
      // TBC : Can this be possible ? not checked in DescrParseAtt ?
2480
      if ($p_filedescr_list[$j]['filename'] == "") {
2481
        continue;
2482
      }
2483
2484
      // ----- Check the filename
2485
      if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')
2486
          && (!file_exists($p_filedescr_list[$j]['filename']))) {
2487
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
2488
        return PclZip::errorCode();
2489
      }
2490
2491
      // ----- Look if it is a file or a dir with no all path remove option
2492
      // or a dir with all its path removed
2493
//      if (   (is_file($p_filedescr_list[$j]['filename']))
2494
//          || (   is_dir($p_filedescr_list[$j]['filename'])
2495
      if (   ($p_filedescr_list[$j]['type'] == 'file')
2496
          || ($p_filedescr_list[$j]['type'] == 'virtual_file')
2497
          || (   ($p_filedescr_list[$j]['type'] == 'folder')
2498
              && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2499
                  || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
2500
          ) {
2501
2502
        // ----- Add the file
2503
        $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2504
                                       $p_options);
2505
        if ($v_result != 1) {
2506
          return $v_result;
2507
        }
2508
2509
        // ----- Store the file infos
2510
        $p_result_list[$v_nb++] = $v_header;
2511
      }
2512
    }
2513
2514
    // ----- Return
2515
    return $v_result;
2516
  }
2517
  // --------------------------------------------------------------------------------
2518
2519
  // --------------------------------------------------------------------------------
2520
  // Function : privAddFile()
2521
  // Description :
2522
  // Parameters :
2523
  // Return Values :
2524
  // --------------------------------------------------------------------------------
2525
  function privAddFile($p_filedescr, &$p_header, &$p_options)
2526
  {
2527
    $v_result=1;
2528
    
2529
    // ----- Working variable
2530
    $p_filename = $p_filedescr['filename'];
2531
2532
    // TBC : Already done in the fileAtt check ... ?
2533
    if ($p_filename == "") {
2534
      // ----- Error log
2535
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2536
2537
      // ----- Return
2538
      return PclZip::errorCode();
2539
    }
2540
  
2541
    // ----- Look for a stored different filename 
2542
    /* TBC : Removed
2543
    if (isset($p_filedescr['stored_filename'])) {
2544
      $v_stored_filename = $p_filedescr['stored_filename'];
2545
    }
2546
    else {
2547
      $v_stored_filename = $p_filedescr['stored_filename'];
2548
    }
2549
    */
2550
2551
    // ----- Set the file properties
2552
    clearstatcache();
2553
    $p_header['version'] = 20;
2554
    $p_header['version_extracted'] = 10;
2555
    $p_header['flag'] = 0;
2556
    $p_header['compression'] = 0;
2557
    $p_header['crc'] = 0;
2558
    $p_header['compressed_size'] = 0;
2559
    $p_header['filename_len'] = strlen($p_filename);
2560
    $p_header['extra_len'] = 0;
2561
    $p_header['disk'] = 0;
2562
    $p_header['internal'] = 0;
2563
    $p_header['offset'] = 0;
2564
    $p_header['filename'] = $p_filename;
2565
// TBC : Removed    $p_header['stored_filename'] = $v_stored_filename;
2566
    $p_header['stored_filename'] = $p_filedescr['stored_filename'];
2567
    $p_header['extra'] = '';
2568
    $p_header['status'] = 'ok';
2569
    $p_header['index'] = -1;
2570
2571
    // ----- Look for regular file
2572
    if ($p_filedescr['type']=='file') {
2573
      $p_header['external'] = 0x00000000;
2574
      $p_header['size'] = filesize($p_filename);
2575
    }
2576
    
2577
    // ----- Look for regular folder
2578
    else if ($p_filedescr['type']=='folder') {
2579
      $p_header['external'] = 0x00000010;
2580
      $p_header['mtime'] = filemtime($p_filename);
2581
      $p_header['size'] = filesize($p_filename);
2582
    }
2583
    
2584
    // ----- Look for virtual file
2585
    else if ($p_filedescr['type'] == 'virtual_file') {
2586
      $p_header['external'] = 0x00000000;
2587
      $p_header['size'] = strlen($p_filedescr['content']);
2588
    }
2589
    
2590
2591
    // ----- Look for filetime
2592
    if (isset($p_filedescr['mtime'])) {
2593
      $p_header['mtime'] = $p_filedescr['mtime'];
2594
    }
2595
    else if ($p_filedescr['type'] == 'virtual_file') {
2596
      $p_header['mtime'] = time();
2597
    }
2598
    else {
2599
      $p_header['mtime'] = filemtime($p_filename);
2600
    }
2601
2602
    // ------ Look for file comment
2603
    if (isset($p_filedescr['comment'])) {
2604
      $p_header['comment_len'] = strlen($p_filedescr['comment']);
2605
      $p_header['comment'] = $p_filedescr['comment'];
2606
    }
2607
    else {
2608
      $p_header['comment_len'] = 0;
2609
      $p_header['comment'] = '';
2610
    }
2611
2612
    // ----- Look for pre-add callback
2613
    if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2614
2615
      // ----- Generate a local information
2616
      $v_local_header = array();
2617
      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2618
2619
      // ----- Call the callback
2620
      // Here I do not use call_user_func() because I need to send a reference to the
2621
      // header.
2622
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2623
      $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2624
      if ($v_result == 0) {
2625
        // ----- Change the file status
2626
        $p_header['status'] = "skipped";
2627
        $v_result = 1;
2628
      }
2629
2630
      // ----- Update the informations
2631
      // Only some fields can be modified
2632
      if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2633
        $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2634
      }
2635
    }
2636
2637
    // ----- Look for empty stored filename
2638
    if ($p_header['stored_filename'] == "") {
2639
      $p_header['status'] = "filtered";
2640
    }
2641
    
2642
    // ----- Check the path length
2643
    if (strlen($p_header['stored_filename']) > 0xFF) {
2644
      $p_header['status'] = 'filename_too_long';
2645
    }
2646
2647
    // ----- Look if no error, or file not skipped
2648
    if ($p_header['status'] == 'ok') {
2649
2650
      // ----- Look for a file
2651
      if ($p_filedescr['type'] == 'file') {
2652
        // ----- Look for using temporary file to zip
2653
        if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 
2654
            && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2655
                || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2656
                    && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
2657
          $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2658
          if ($v_result < PCLZIP_ERR_NO_ERROR) {
2659
            return $v_result;
2660
          }
2661
        }
2662
        
2663
        // ----- Use "in memory" zip algo
2664
        else {
2665
2666
        // ----- Open the source file
2667 View Code Duplication
        if (($v_file = @fopen($p_filename, "rb")) == 0) {
2668
          PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2669
          return PclZip::errorCode();
2670
        }
2671
2672
        // ----- Read the file content
2673
        $v_content = @fread($v_file, $p_header['size']);
2674
2675
        // ----- Close the file
2676
        @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...
2677
2678
        // ----- Calculate the CRC
2679
        $p_header['crc'] = @crc32($v_content);
2680
        
2681
        // ----- Look for no compression
2682 View Code Duplication
        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2683
          // ----- Set header parameters
2684
          $p_header['compressed_size'] = $p_header['size'];
2685
          $p_header['compression'] = 0;
2686
        }
2687
        
2688
        // ----- Look for normal compression
2689
        else {
2690
          // ----- Compress the content
2691
          $v_content = @gzdeflate($v_content);
2692
2693
          // ----- Set header parameters
2694
          $p_header['compressed_size'] = strlen($v_content);
2695
          $p_header['compression'] = 8;
2696
        }
2697
        
2698
        // ----- Call the header generation
2699
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2700
          @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...
2701
          return $v_result;
2702
        }
2703
2704
        // ----- Write the compressed (or not) content
2705
        @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...
2706
2707
        }
2708
2709
      }
2710
2711
      // ----- Look for a virtual file (a file from string)
2712
      else if ($p_filedescr['type'] == 'virtual_file') {
2713
          
2714
        $v_content = $p_filedescr['content'];
2715
2716
        // ----- Calculate the CRC
2717
        $p_header['crc'] = @crc32($v_content);
2718
        
2719
        // ----- Look for no compression
2720 View Code Duplication
        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2721
          // ----- Set header parameters
2722
          $p_header['compressed_size'] = $p_header['size'];
2723
          $p_header['compression'] = 0;
2724
        }
2725
        
2726
        // ----- Look for normal compression
2727
        else {
2728
          // ----- Compress the content
2729
          $v_content = @gzdeflate($v_content);
2730
2731
          // ----- Set header parameters
2732
          $p_header['compressed_size'] = strlen($v_content);
2733
          $p_header['compression'] = 8;
2734
        }
2735
        
2736
        // ----- Call the header generation
2737
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2738
          @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...
2739
          return $v_result;
2740
        }
2741
2742
        // ----- Write the compressed (or not) content
2743
        @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...
2744
      }
2745
2746
      // ----- Look for a directory
2747
      else if ($p_filedescr['type'] == 'folder') {
2748
        // ----- Look for directory last '/'
2749
        if (@substr($p_header['stored_filename'], -1) != '/') {
2750
          $p_header['stored_filename'] .= '/';
2751
        }
2752
2753
        // ----- Set the file properties
2754
        $p_header['size'] = 0;
2755
        //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
2756
        $p_header['external'] = 0x00000010;   // Value for a folder : to be checked
2757
2758
        // ----- Call the header generation
2759
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2760
        {
2761
          return $v_result;
2762
        }
2763
      }
2764
    }
2765
2766
    // ----- Look for post-add callback
2767
    if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2768
2769
      // ----- Generate a local information
2770
      $v_local_header = array();
2771
      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2772
2773
      // ----- Call the callback
2774
      // Here I do not use call_user_func() because I need to send a reference to the
2775
      // header.
2776
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2777
      $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2778
      if ($v_result == 0) {
2779
        // ----- Ignored
2780
        $v_result = 1;
2781
      }
2782
2783
      // ----- Update the informations
2784
      // Nothing can be modified
2785
    }
2786
2787
    // ----- Return
2788
    return $v_result;
2789
  }
2790
  // --------------------------------------------------------------------------------
2791
2792
  // --------------------------------------------------------------------------------
2793
  // Function : privAddFileUsingTempFile()
2794
  // Description :
2795
  // Parameters :
2796
  // Return Values :
2797
  // --------------------------------------------------------------------------------
2798
  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...
2799
  {
2800
    $v_result=PCLZIP_ERR_NO_ERROR;
2801
    
2802
    // ----- Working variable
2803
    $p_filename = $p_filedescr['filename'];
2804
2805
2806
    // ----- Open the source file
2807 View Code Duplication
    if (($v_file = @fopen($p_filename, "rb")) == 0) {
2808
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2809
      return PclZip::errorCode();
2810
    }
2811
2812
    // ----- Creates a compressed temporary file
2813
    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2814 View Code Duplication
    if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2815
      fclose($v_file);
2816
      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2817
      return PclZip::errorCode();
2818
    }
2819
2820
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2821
    $v_size = filesize($p_filename);
2822
    while ($v_size != 0) {
2823
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2824
      $v_buffer = @fread($v_file, $v_read_size);
2825
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2826
      @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...
2827
      $v_size -= $v_read_size;
2828
    }
2829
2830
    // ----- Close the file
2831
    @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...
2832
    @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...
2833
2834
    // ----- Check the minimum file size
2835 View Code Duplication
    if (filesize($v_gzip_temp_name) < 18) {
2836
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
2837
      return PclZip::errorCode();
2838
    }
2839
2840
    // ----- Extract the compressed attributes
2841 View Code Duplication
    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2842
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2843
      return PclZip::errorCode();
2844
    }
2845
2846
    // ----- Read the gzip file header
2847
    $v_binary_data = @fread($v_file_compressed, 10);
2848
    $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
2849
2850
    // ----- Check some parameters
2851
    $v_data_header['os'] = bin2hex($v_data_header['os']);
2852
2853
    // ----- Read the gzip file footer
2854
    @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...
2855
    $v_binary_data = @fread($v_file_compressed, 8);
2856
    $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2857
2858
    // ----- Set the attributes
2859
    $p_header['compression'] = ord($v_data_header['cm']);
2860
    //$p_header['mtime'] = $v_data_header['mtime'];
2861
    $p_header['crc'] = $v_data_footer['crc'];
2862
    $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
2863
2864
    // ----- Close the file
2865
    @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...
2866
2867
    // ----- Call the header generation
2868
    if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2869
      return $v_result;
2870
    }
2871
2872
    // ----- Add the compressed data
2873 View Code Duplication
    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
2874
    {
2875
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2876
      return PclZip::errorCode();
2877
    }
2878
2879
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2880
    fseek($v_file_compressed, 10);
2881
    $v_size = $p_header['compressed_size'];
2882 View Code Duplication
    while ($v_size != 0)
2883
    {
2884
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2885
      $v_buffer = @fread($v_file_compressed, $v_read_size);
2886
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2887
      @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...
2888
      $v_size -= $v_read_size;
2889
    }
2890
2891
    // ----- Close the file
2892
    @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...
2893
2894
    // ----- Unlink the temporary file
2895
    @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...
2896
    
2897
    // ----- Return
2898
    return $v_result;
2899
  }
2900
  // --------------------------------------------------------------------------------
2901
2902
  // --------------------------------------------------------------------------------
2903
  // Function : privCalculateStoredFilename()
2904
  // Description :
2905
  //   Based on file descriptor properties and global options, this method
2906
  //   calculate the filename that will be stored in the archive.
2907
  // Parameters :
2908
  // Return Values :
2909
  // --------------------------------------------------------------------------------
2910
  function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2911
  {
2912
    $v_result=1;
2913
    
2914
    // ----- Working variables
2915
    $p_filename = $p_filedescr['filename'];
2916
    if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2917
      $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2918
    }
2919
    else {
2920
      $p_add_dir = '';
2921
    }
2922
    if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2923
      $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2924
    }
2925
    else {
2926
      $p_remove_dir = '';
2927
    }
2928
    if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2929
      $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2930
    }
2931
    else {
2932
      $p_remove_all_dir = 0;
2933
    }
2934
2935
2936
    // ----- Look for full name change
2937
    if (isset($p_filedescr['new_full_name'])) {
2938
      // ----- Remove drive letter if any
2939
      $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2940
    }
2941
    
2942
    // ----- Look for path and/or short name change
2943
    else {
2944
2945
      // ----- Look for short name change
2946
      // Its when we cahnge just the filename but not the path
2947
      if (isset($p_filedescr['new_short_name'])) {
2948
        $v_path_info = pathinfo($p_filename);
2949
        $v_dir = '';
2950
        if ($v_path_info['dirname'] != '') {
2951
          $v_dir = $v_path_info['dirname'].'/';
2952
        }
2953
        $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2954
      }
2955
      else {
2956
        // ----- Calculate the stored filename
2957
        $v_stored_filename = $p_filename;
2958
      }
2959
2960
      // ----- Look for all path to remove
2961
      if ($p_remove_all_dir) {
2962
        $v_stored_filename = basename($p_filename);
2963
      }
2964
      // ----- Look for partial path remove
2965
      else if ($p_remove_dir != "") {
2966
        if (substr($p_remove_dir, -1) != '/')
2967
          $p_remove_dir .= "/";
2968
2969
        if (   (substr($p_filename, 0, 2) == "./")
2970
            || (substr($p_remove_dir, 0, 2) == "./")) {
2971
            
2972 View Code Duplication
          if (   (substr($p_filename, 0, 2) == "./")
2973
              && (substr($p_remove_dir, 0, 2) != "./")) {
2974
            $p_remove_dir = "./".$p_remove_dir;
2975
          }
2976 View Code Duplication
          if (   (substr($p_filename, 0, 2) != "./")
2977
              && (substr($p_remove_dir, 0, 2) == "./")) {
2978
            $p_remove_dir = substr($p_remove_dir, 2);
2979
          }
2980
        }
2981
2982
        $v_compare = PclZipUtilPathInclusion($p_remove_dir,
2983
                                             $v_stored_filename);
2984
        if ($v_compare > 0) {
2985
          if ($v_compare == 2) {
2986
            $v_stored_filename = "";
2987
          }
2988
          else {
2989
            $v_stored_filename = substr($v_stored_filename,
2990
                                        strlen($p_remove_dir));
2991
          }
2992
        }
2993
      }
2994
      
2995
      // ----- Remove drive letter if any
2996
      $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
2997
      
2998
      // ----- Look for path to add
2999
      if ($p_add_dir != "") {
3000
        if (substr($p_add_dir, -1) == "/")
3001
          $v_stored_filename = $p_add_dir.$v_stored_filename;
3002
        else
3003
          $v_stored_filename = $p_add_dir."/".$v_stored_filename;
3004
      }
3005
    }
3006
3007
    // ----- Filename (reduce the path of stored name)
3008
    $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
3009
    $p_filedescr['stored_filename'] = $v_stored_filename;
3010
    
3011
    // ----- Return
3012
    return $v_result;
3013
  }
3014
  // --------------------------------------------------------------------------------
3015
3016
  // --------------------------------------------------------------------------------
3017
  // Function : privWriteFileHeader()
3018
  // Description :
3019
  // Parameters :
3020
  // Return Values :
3021
  // --------------------------------------------------------------------------------
3022
  function privWriteFileHeader(&$p_header)
3023
  {
3024
    $v_result=1;
3025
3026
    // ----- Store the offset position of the file
3027
    $p_header['offset'] = ftell($this->zip_fd);
3028
3029
    // ----- Transform UNIX mtime to DOS format mdate/mtime
3030
    $v_date = getdate($p_header['mtime']);
3031
    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3032
    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3033
3034
    // ----- Packed data
3035
    $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
3036
	                      $p_header['version_extracted'], $p_header['flag'],
3037
                          $p_header['compression'], $v_mtime, $v_mdate,
3038
                          $p_header['crc'], $p_header['compressed_size'],
3039
						  $p_header['size'],
3040
                          strlen($p_header['stored_filename']),
3041
						  $p_header['extra_len']);
3042
3043
    // ----- Write the first 148 bytes of the header in the archive
3044
    fputs($this->zip_fd, $v_binary_data, 30);
3045
3046
    // ----- Write the variable fields
3047 View Code Duplication
    if (strlen($p_header['stored_filename']) != 0)
3048
    {
3049
      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3050
    }
3051 View Code Duplication
    if ($p_header['extra_len'] != 0)
3052
    {
3053
      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3054
    }
3055
3056
    // ----- Return
3057
    return $v_result;
3058
  }
3059
  // --------------------------------------------------------------------------------
3060
3061
  // --------------------------------------------------------------------------------
3062
  // Function : privWriteCentralFileHeader()
3063
  // Description :
3064
  // Parameters :
3065
  // Return Values :
3066
  // --------------------------------------------------------------------------------
3067
  function privWriteCentralFileHeader(&$p_header)
3068
  {
3069
    $v_result=1;
3070
3071
    // TBC
3072
    //for(reset($p_header); $key = key($p_header); next($p_header)) {
3073
    //}
3074
3075
    // ----- Transform UNIX mtime to DOS format mdate/mtime
3076
    $v_date = getdate($p_header['mtime']);
3077
    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3078
    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3079
3080
3081
    // ----- Packed data
3082
    $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
3083
	                      $p_header['version'], $p_header['version_extracted'],
3084
                          $p_header['flag'], $p_header['compression'],
3085
						  $v_mtime, $v_mdate, $p_header['crc'],
3086
                          $p_header['compressed_size'], $p_header['size'],
3087
                          strlen($p_header['stored_filename']),
3088
						  $p_header['extra_len'], $p_header['comment_len'],
3089
                          $p_header['disk'], $p_header['internal'],
3090
						  $p_header['external'], $p_header['offset']);
3091
3092
    // ----- Write the 42 bytes of the header in the zip file
3093
    fputs($this->zip_fd, $v_binary_data, 46);
3094
3095
    // ----- Write the variable fields
3096 View Code Duplication
    if (strlen($p_header['stored_filename']) != 0)
3097
    {
3098
      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3099
    }
3100 View Code Duplication
    if ($p_header['extra_len'] != 0)
3101
    {
3102
      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3103
    }
3104
    if ($p_header['comment_len'] != 0)
3105
    {
3106
      fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
3107
    }
3108
3109
    // ----- Return
3110
    return $v_result;
3111
  }
3112
  // --------------------------------------------------------------------------------
3113
3114
  // --------------------------------------------------------------------------------
3115
  // Function : privWriteCentralHeader()
3116
  // Description :
3117
  // Parameters :
3118
  // Return Values :
3119
  // --------------------------------------------------------------------------------
3120
  function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3121
  {
3122
    $v_result=1;
3123
3124
    // ----- Packed data
3125
    $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
3126
	                      $p_nb_entries, $p_size,
3127
						  $p_offset, strlen($p_comment));
3128
3129
    // ----- Write the 22 bytes of the header in the zip file
3130
    fputs($this->zip_fd, $v_binary_data, 22);
3131
3132
    // ----- Write the variable fields
3133
    if (strlen($p_comment) != 0)
3134
    {
3135
      fputs($this->zip_fd, $p_comment, strlen($p_comment));
3136
    }
3137
3138
    // ----- Return
3139
    return $v_result;
3140
  }
3141
  // --------------------------------------------------------------------------------
3142
3143
  // --------------------------------------------------------------------------------
3144
  // Function : privList()
3145
  // Description :
3146
  // Parameters :
3147
  // Return Values :
3148
  // --------------------------------------------------------------------------------
3149
  function privList(&$p_list)
3150
  {
3151
    $v_result=1;
3152
3153
    // ----- Magic quotes trick
3154
    $this->privDisableMagicQuotes();
3155
3156
    // ----- Open the zip file
3157 View Code Duplication
    if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
3158
    {
3159
      // ----- Magic quotes trick
3160
      $this->privSwapBackMagicQuotes();
3161
      
3162
      // ----- Error log
3163
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
3164
3165
      // ----- Return
3166
      return PclZip::errorCode();
3167
    }
3168
3169
    // ----- Read the central directory informations
3170
    $v_central_dir = array();
3171
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3172
    {
3173
      $this->privSwapBackMagicQuotes();
3174
      return $v_result;
3175
    }
3176
3177
    // ----- Go to beginning of Central Dir
3178
    @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...
3179 View Code Duplication
    if (@fseek($this->zip_fd, $v_central_dir['offset']))
3180
    {
3181
      $this->privSwapBackMagicQuotes();
3182
3183
      // ----- Error log
3184
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3185
3186
      // ----- Return
3187
      return PclZip::errorCode();
3188
    }
3189
3190
    // ----- Read each entry
3191
    for ($i=0; $i<$v_central_dir['entries']; $i++)
3192
    {
3193
      // ----- Read the file header
3194
      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3195
      {
3196
        $this->privSwapBackMagicQuotes();
3197
        return $v_result;
3198
      }
3199
      $v_header['index'] = $i;
3200
3201
      // ----- Get the only interesting attributes
3202
      $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3203
      unset($v_header);
3204
    }
3205
3206
    // ----- Close the zip file
3207
    $this->privCloseFd();
3208
3209
    // ----- Magic quotes trick
3210
    $this->privSwapBackMagicQuotes();
3211
3212
    // ----- Return
3213
    return $v_result;
3214
  }
3215
  // --------------------------------------------------------------------------------
3216
3217
  // --------------------------------------------------------------------------------
3218
  // Function : privConvertHeader2FileInfo()
3219
  // Description :
3220
  //   This function takes the file informations from the central directory
3221
  //   entries and extract the interesting parameters that will be given back.
3222
  //   The resulting file infos are set in the array $p_info
3223
  //     $p_info['filename'] : Filename with full path. Given by user (add),
3224
  //                           extracted in the filesystem (extract).
3225
  //     $p_info['stored_filename'] : Stored filename in the archive.
3226
  //     $p_info['size'] = Size of the file.
3227
  //     $p_info['compressed_size'] = Compressed size of the file.
3228
  //     $p_info['mtime'] = Last modification date of the file.
3229
  //     $p_info['comment'] = Comment associated with the file.
3230
  //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3231
  //     $p_info['status'] = status of the action on the file.
3232
  //     $p_info['crc'] = CRC of the file content.
3233
  // Parameters :
3234
  // Return Values :
3235
  // --------------------------------------------------------------------------------
3236
  function privConvertHeader2FileInfo($p_header, &$p_info)
3237
  {
3238
    $v_result=1;
3239
3240
    // ----- Get the interesting attributes
3241
    $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
3242
    $p_info['filename'] = $v_temp_path;
3243
    $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
3244
    $p_info['stored_filename'] = $v_temp_path;
3245
    $p_info['size'] = $p_header['size'];
3246
    $p_info['compressed_size'] = $p_header['compressed_size'];
3247
    $p_info['mtime'] = $p_header['mtime'];
3248
    $p_info['comment'] = $p_header['comment'];
3249
    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3250
    $p_info['index'] = $p_header['index'];
3251
    $p_info['status'] = $p_header['status'];
3252
    $p_info['crc'] = $p_header['crc'];
3253
3254
    // ----- Return
3255
    return $v_result;
3256
  }
3257
  // --------------------------------------------------------------------------------
3258
3259
  // --------------------------------------------------------------------------------
3260
  // Function : privExtractByRule()
3261
  // Description :
3262
  //   Extract a file or directory depending of rules (by index, by name, ...)
3263
  // Parameters :
3264
  //   $p_file_list : An array where will be placed the properties of each
3265
  //                  extracted file
3266
  //   $p_path : Path to add while writing the extracted files
3267
  //   $p_remove_path : Path to remove (from the file memorized path) while writing the
3268
  //                    extracted files. If the path does not match the file path,
3269
  //                    the file is extracted with its memorized path.
3270
  //                    $p_remove_path does not apply to 'list' mode.
3271
  //                    $p_path and $p_remove_path are commulative.
3272
  // Return Values :
3273
  //   1 on success,0 or less on error (see error code list)
3274
  // --------------------------------------------------------------------------------
3275
  function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3276
  {
3277
    $v_result=1;
3278
3279
    // ----- Magic quotes trick
3280
    $this->privDisableMagicQuotes();
3281
3282
    // ----- Check the path
3283
    if (   ($p_path == "")
3284
	    || (   (substr($p_path, 0, 1) != "/")
3285
		    && (substr($p_path, 0, 3) != "../")
3286
			&& (substr($p_path,1,2)!=":/")))
3287
      $p_path = "./".$p_path;
3288
3289
    // ----- Reduce the path last (and duplicated) '/'
3290
    if (($p_path != "./") && ($p_path != "/"))
3291
    {
3292
      // ----- Look for the path end '/'
3293
      while (substr($p_path, -1) == "/")
3294
      {
3295
        $p_path = substr($p_path, 0, strlen($p_path)-1);
3296
      }
3297
    }
3298
3299
    // ----- Look for path to remove format (should end by /)
3300
    if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3301
    {
3302
      $p_remove_path .= '/';
3303
    }
3304
    $p_remove_path_size = strlen($p_remove_path);
3305
3306
    // ----- Open the zip file
3307
    if (($v_result = $this->privOpenFd('rb')) != 1)
3308
    {
3309
      $this->privSwapBackMagicQuotes();
3310
      return $v_result;
3311
    }
3312
3313
    // ----- Read the central directory informations
3314
    $v_central_dir = array();
3315
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3316
    {
3317
      // ----- Close the zip file
3318
      $this->privCloseFd();
3319
      $this->privSwapBackMagicQuotes();
3320
3321
      return $v_result;
3322
    }
3323
3324
    // ----- Start at beginning of Central Dir
3325
    $v_pos_entry = $v_central_dir['offset'];
3326
3327
    // ----- Read each entry
3328
    $j_start = 0;
3329
    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3330
    {
3331
3332
      // ----- Read next Central dir entry
3333
      @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...
3334 View Code Duplication
      if (@fseek($this->zip_fd, $v_pos_entry))
3335
      {
3336
        // ----- Close the zip file
3337
        $this->privCloseFd();
3338
        $this->privSwapBackMagicQuotes();
3339
3340
        // ----- Error log
3341
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3342
3343
        // ----- Return
3344
        return PclZip::errorCode();
3345
      }
3346
3347
      // ----- Read the file header
3348
      $v_header = array();
3349
      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3350
      {
3351
        // ----- Close the zip file
3352
        $this->privCloseFd();
3353
        $this->privSwapBackMagicQuotes();
3354
3355
        return $v_result;
3356
      }
3357
3358
      // ----- Store the index
3359
      $v_header['index'] = $i;
3360
3361
      // ----- Store the file position
3362
      $v_pos_entry = ftell($this->zip_fd);
3363
3364
      // ----- Look for the specific extract rules
3365
      $v_extract = false;
3366
3367
      // ----- Look for extract by name rule
3368
      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
3369
          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3370
3371
          // ----- Look if the filename is in the list
3372
          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3373
3374
              // ----- Look for a directory
3375
              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3376
3377
                  // ----- Look if the directory is in the filename path
3378
                  if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3379
                      && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3380
                      $v_extract = true;
3381
                  }
3382
              }
3383
              // ----- Look for a filename
3384
              elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3385
                  $v_extract = true;
3386
              }
3387
          }
3388
      }
3389
3390
      // ----- Look for extract by ereg rule
3391
      // ereg() is deprecated with PHP 5.3
3392
      /* 
3393
      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
3394
               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3395
3396
          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3397
              $v_extract = true;
3398
          }
3399
      }
3400
      */
3401
3402
      // ----- Look for extract by preg rule
3403 View Code Duplication
      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
3404
               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3405
3406
          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3407
              $v_extract = true;
3408
          }
3409
      }
3410
3411
      // ----- Look for extract by index rule
3412
      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3413
               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3414
          
3415
          // ----- Look if the index is in the list
3416
          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3417
3418
              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3419
                  $v_extract = true;
3420
              }
3421
              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3422
                  $j_start = $j+1;
3423
              }
3424
3425
              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3426
                  break;
3427
              }
3428
          }
3429
      }
3430
3431
      // ----- Look for no rule, which means extract all the archive
3432
      else {
3433
          $v_extract = true;
3434
      }
3435
3436
	  // ----- Check compression method
3437
	  if (   ($v_extract)
3438
	      && (   ($v_header['compression'] != 8)
3439
		      && ($v_header['compression'] != 0))) {
3440
          $v_header['status'] = 'unsupported_compression';
3441
3442
          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3443
          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3444
		      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3445
3446
              $this->privSwapBackMagicQuotes();
3447
              
3448
              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3449
			                       "Filename '".$v_header['stored_filename']."' is "
3450
				  	    	  	   ."compressed by an unsupported compression "
3451
				  	    	  	   ."method (".$v_header['compression'].") ");
3452
3453
              return PclZip::errorCode();
3454
		  }
3455
	  }
3456
	  
3457
	  // ----- Check encrypted files
3458
	  if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3459
          $v_header['status'] = 'unsupported_encryption';
3460
3461
          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3462
          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3463
		      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3464
3465
              $this->privSwapBackMagicQuotes();
3466
3467
              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3468
			                       "Unsupported encryption for "
3469
				  	    	  	   ." filename '".$v_header['stored_filename']
3470
								   ."'");
3471
3472
              return PclZip::errorCode();
3473
		  }
3474
    }
3475
3476
      // ----- Look for real extraction
3477
      if (($v_extract) && ($v_header['status'] != 'ok')) {
3478
          $v_result = $this->privConvertHeader2FileInfo($v_header,
3479
		                                        $p_file_list[$v_nb_extracted++]);
3480
          if ($v_result != 1) {
3481
              $this->privCloseFd();
3482
              $this->privSwapBackMagicQuotes();
3483
              return $v_result;
3484
          }
3485
3486
          $v_extract = false;
3487
      }
3488
      
3489
      // ----- Look for real extraction
3490
      if ($v_extract)
3491
      {
3492
3493
        // ----- Go to the file position
3494
        @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...
3495 View Code Duplication
        if (@fseek($this->zip_fd, $v_header['offset']))
3496
        {
3497
          // ----- Close the zip file
3498
          $this->privCloseFd();
3499
3500
          $this->privSwapBackMagicQuotes();
3501
3502
          // ----- Error log
3503
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3504
3505
          // ----- Return
3506
          return PclZip::errorCode();
3507
        }
3508
3509
        // ----- Look for extraction as string
3510
        if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3511
3512
          $v_string = '';
3513
3514
          // ----- Extracting the file
3515
          $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3516
          if ($v_result1 < 1) {
3517
            $this->privCloseFd();
3518
            $this->privSwapBackMagicQuotes();
3519
            return $v_result1;
3520
          }
3521
3522
          // ----- Get the only interesting attributes
3523 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3524
          {
3525
            // ----- Close the zip file
3526
            $this->privCloseFd();
3527
            $this->privSwapBackMagicQuotes();
3528
3529
            return $v_result;
3530
          }
3531
3532
          // ----- Set the file content
3533
          $p_file_list[$v_nb_extracted]['content'] = $v_string;
3534
3535
          // ----- Next extracted file
3536
          $v_nb_extracted++;
3537
          
3538
          // ----- Look for user callback abort
3539
          if ($v_result1 == 2) {
3540
          	break;
3541
          }
3542
        }
3543
        // ----- Look for extraction in standard output
3544
        elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3545
		        && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3546
          // ----- Extracting the file in standard output
3547
          $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3548
          if ($v_result1 < 1) {
3549
            $this->privCloseFd();
3550
            $this->privSwapBackMagicQuotes();
3551
            return $v_result1;
3552
          }
3553
3554
          // ----- Get the only interesting attributes
3555 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3556
            $this->privCloseFd();
3557
            $this->privSwapBackMagicQuotes();
3558
            return $v_result;
3559
          }
3560
3561
          // ----- Look for user callback abort
3562
          if ($v_result1 == 2) {
3563
          	break;
3564
          }
3565
        }
3566
        // ----- Look for normal extraction
3567
        else {
3568
          // ----- Extracting the file
3569
          $v_result1 = $this->privExtractFile($v_header,
3570
		                                      $p_path, $p_remove_path,
3571
											  $p_remove_all_path,
3572
											  $p_options);
3573
          if ($v_result1 < 1) {
3574
            $this->privCloseFd();
3575
            $this->privSwapBackMagicQuotes();
3576
            return $v_result1;
3577
          }
3578
3579
          // ----- Get the only interesting attributes
3580 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3581
          {
3582
            // ----- Close the zip file
3583
            $this->privCloseFd();
3584
            $this->privSwapBackMagicQuotes();
3585
3586
            return $v_result;
3587
          }
3588
3589
          // ----- Look for user callback abort
3590
          if ($v_result1 == 2) {
3591
          	break;
3592
          }
3593
        }
3594
      }
3595
    }
3596
3597
    // ----- Close the zip file
3598
    $this->privCloseFd();
3599
    $this->privSwapBackMagicQuotes();
3600
3601
    // ----- Return
3602
    return $v_result;
3603
  }
3604
  // --------------------------------------------------------------------------------
3605
3606
  // --------------------------------------------------------------------------------
3607
  // Function : privExtractFile()
3608
  // Description :
3609
  // Parameters :
3610
  // Return Values :
3611
  //
3612
  // 1 : ... ?
3613
  // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3614
  // --------------------------------------------------------------------------------
3615
  function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3616
  {
3617
    $v_result=1;
3618
3619
    // ----- Read the file header
3620
    if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3621
    {
3622
      // ----- Return
3623
      return $v_result;
3624
    }
3625
3626
3627
    // ----- Check that the file header is coherent with $p_entry info
3628
    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
3629
        // TBC
3630
    }
3631
3632
    // ----- Look for all path to remove
3633
    if ($p_remove_all_path == true) {
3634
        // ----- Look for folder entry that not need to be extracted
3635
        if (($p_entry['external']&0x00000010)==0x00000010) {
3636
3637
            $p_entry['status'] = "filtered";
3638
3639
            return $v_result;
3640
        }
3641
3642
        // ----- Get the basename of the path
3643
        $p_entry['filename'] = basename($p_entry['filename']);
3644
    }
3645
3646
    // ----- Look for path to remove
3647
    else if ($p_remove_path != "")
3648
    {
3649
      if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3650
      {
3651
3652
        // ----- Change the file status
3653
        $p_entry['status'] = "filtered";
3654
3655
        // ----- Return
3656
        return $v_result;
3657
      }
3658
3659
      $p_remove_path_size = strlen($p_remove_path);
3660
      if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3661
      {
3662
3663
        // ----- Remove the path
3664
        $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3665
3666
      }
3667
    }
3668
3669
    // ----- Add the path
3670
    if ($p_path != '') {
3671
      $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3672
    }
3673
    
3674
    // ----- Check a base_dir_restriction
3675
    if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3676
      $v_inclusion
3677
      = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3678
                                $p_entry['filename']); 
3679 View Code Duplication
      if ($v_inclusion == 0) {
3680
3681
        PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3682
			                     "Filename '".$p_entry['filename']."' is "
3683
								 ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3684
3685
        return PclZip::errorCode();
3686
      }
3687
    }
3688
3689
    // ----- Look for pre-extract callback
3690 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3691
3692
      // ----- Generate a local information
3693
      $v_local_header = array();
3694
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3695
3696
      // ----- Call the callback
3697
      // Here I do not use call_user_func() because I need to send a reference to the
3698
      // header.
3699
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3700
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3701
      if ($v_result == 0) {
3702
        // ----- Change the file status
3703
        $p_entry['status'] = "skipped";
3704
        $v_result = 1;
3705
      }
3706
      
3707
      // ----- Look for abort result
3708
      if ($v_result == 2) {
3709
        // ----- This status is internal and will be changed in 'skipped'
3710
        $p_entry['status'] = "aborted";
3711
      	$v_result = PCLZIP_ERR_USER_ABORTED;
3712
      }
3713
3714
      // ----- Update the informations
3715
      // Only some fields can be modified
3716
      $p_entry['filename'] = $v_local_header['filename'];
3717
    }
3718
3719
3720
    // ----- Look if extraction should be done
3721
    if ($p_entry['status'] == 'ok') {
3722
3723
    // ----- Look for specific actions while the file exist
3724
    if (file_exists($p_entry['filename']))
3725
    {
3726
3727
      // ----- Look if file is a directory
3728
      if (is_dir($p_entry['filename']))
3729
      {
3730
3731
        // ----- Change the file status
3732
        $p_entry['status'] = "already_a_directory";
3733
        
3734
        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3735
        // For historical reason first PclZip implementation does not stop
3736
        // when this kind of error occurs.
3737 View Code Duplication
        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3738
		    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3739
3740
            PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3741
			                     "Filename '".$p_entry['filename']."' is "
3742
								 ."already used by an existing directory");
3743
3744
            return PclZip::errorCode();
3745
		    }
3746
      }
3747
      // ----- Look if file is write protected
3748
      else if (!is_writeable($p_entry['filename']))
3749
      {
3750
3751
        // ----- Change the file status
3752
        $p_entry['status'] = "write_protected";
3753
3754
        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3755
        // For historical reason first PclZip implementation does not stop
3756
        // when this kind of error occurs.
3757 View Code Duplication
        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3758
		    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3759
3760
            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3761
			                     "Filename '".$p_entry['filename']."' exists "
3762
								 ."and is write protected");
3763
3764
            return PclZip::errorCode();
3765
		    }
3766
      }
3767
3768
      // ----- Look if the extracted file is older
3769
      else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3770
      {
3771
        // ----- Change the file status
3772
        if (   (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
3773
		    && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3774
	  	  }
3775 View Code Duplication
		    else {
3776
            $p_entry['status'] = "newer_exist";
3777
3778
            // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3779
            // For historical reason first PclZip implementation does not stop
3780
            // when this kind of error occurs.
3781
            if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3782
		        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3783
3784
                PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3785
			             "Newer version of '".$p_entry['filename']."' exists "
3786
					    ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3787
3788
                return PclZip::errorCode();
3789
		      }
3790
		    }
3791
      }
3792
      else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
3793
      }
3794
    }
3795
3796
    // ----- Check the directory availability and create it if necessary
3797
    else {
3798
      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3799
        $v_dir_to_check = $p_entry['filename'];
3800
      else if (!strstr($p_entry['filename'], "/"))
3801
        $v_dir_to_check = "";
3802
      else
3803
        $v_dir_to_check = dirname($p_entry['filename']);
3804
3805
        if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3806
  
3807
          // ----- Change the file status
3808
          $p_entry['status'] = "path_creation_fail";
3809
  
3810
          // ----- Return
3811
          //return $v_result;
3812
          $v_result = 1;
3813
        }
3814
      }
3815
    }
3816
3817
    // ----- Look if extraction should be done
3818
    if ($p_entry['status'] == 'ok') {
3819
3820
      // ----- Do the extraction (if not a folder)
3821
      if (!(($p_entry['external']&0x00000010)==0x00000010))
3822
      {
3823
        // ----- Look for not compressed file
3824
        if ($p_entry['compression'] == 0) {
3825
3826
    		  // ----- Opening destination file
3827 View Code Duplication
          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3828
          {
3829
3830
            // ----- Change the file status
3831
            $p_entry['status'] = "write_error";
3832
3833
            // ----- Return
3834
            return $v_result;
3835
          }
3836
3837
3838
          // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3839
          $v_size = $p_entry['compressed_size'];
3840 View Code Duplication
          while ($v_size != 0)
3841
          {
3842
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3843
            $v_buffer = @fread($this->zip_fd, $v_read_size);
3844
            /* Try to speed up the code
3845
            $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3846
            @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3847
            */
3848
            @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...
3849
            $v_size -= $v_read_size;
3850
          }
3851
3852
          // ----- Closing the destination file
3853
          fclose($v_dest_file);
3854
3855
          // ----- Change the file mtime
3856
          touch($p_entry['filename'], $p_entry['mtime']);
3857
          
3858
3859
        }
3860
        else {
3861
          // ----- TBC
3862
          // Need to be finished
3863 View Code Duplication
          if (($p_entry['flag'] & 1) == 1) {
3864
            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
3865
            return PclZip::errorCode();
3866
          }
3867
3868
3869
          // ----- Look for using temporary file to unzip
3870
          if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 
3871
              && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
3872
                  || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
3873
                      && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
3874
            $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3875
            if ($v_result < PCLZIP_ERR_NO_ERROR) {
3876
              return $v_result;
3877
            }
3878
          }
3879
          
3880
          // ----- Look for extract in memory
3881
          else {
3882
3883
          
3884
            // ----- Read the compressed file in a buffer (one shot)
3885
            $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3886
            
3887
            // ----- Decompress the file
3888
            $v_file_content = @gzinflate($v_buffer);
3889
            unset($v_buffer);
3890
            if ($v_file_content === FALSE) {
3891
  
3892
              // ----- Change the file status
3893
              // TBC
3894
              $p_entry['status'] = "error";
3895
              
3896
              return $v_result;
3897
            }
3898
            
3899
            // ----- Opening destination file
3900 View Code Duplication
            if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3901
  
3902
              // ----- Change the file status
3903
              $p_entry['status'] = "write_error";
3904
  
3905
              return $v_result;
3906
            }
3907
  
3908
            // ----- Write the uncompressed data
3909
            @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...
3910
            unset($v_file_content);
3911
  
3912
            // ----- Closing the destination file
3913
            @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...
3914
            
3915
          }
3916
3917
          // ----- Change the file mtime
3918
          @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...
3919
        }
3920
3921
        // ----- Look for chmod option
3922
        if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3923
3924
          // ----- Change the mode of the file
3925
          @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...
3926
        }
3927
3928
      }
3929
    }
3930
3931
  	// ----- Change abort status
3932 View Code Duplication
  	if ($p_entry['status'] == "aborted") {
3933
        $p_entry['status'] = "skipped";
3934
  	}
3935
	
3936
    // ----- Look for post-extract callback
3937
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3938
3939
      // ----- Generate a local information
3940
      $v_local_header = array();
3941
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3942
3943
      // ----- Call the callback
3944
      // Here I do not use call_user_func() because I need to send a reference to the
3945
      // header.
3946
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3947
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3948
3949
      // ----- Look for abort result
3950
      if ($v_result == 2) {
3951
      	$v_result = PCLZIP_ERR_USER_ABORTED;
3952
      }
3953
    }
3954
3955
    // ----- Return
3956
    return $v_result;
3957
  }
3958
  // --------------------------------------------------------------------------------
3959
3960
  // --------------------------------------------------------------------------------
3961
  // Function : privExtractFileUsingTempFile()
3962
  // Description :
3963
  // Parameters :
3964
  // Return Values :
3965
  // --------------------------------------------------------------------------------
3966
  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...
3967
  {
3968
    $v_result=1;
3969
        
3970
    // ----- Creates a temporary file
3971
    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
3972 View Code Duplication
    if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3973
      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...
3974
      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
3975
      return PclZip::errorCode();
3976
    }
3977
3978
3979
    // ----- Write gz file format header
3980
    $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
3981
    @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...
3982
3983
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3984
    $v_size = $p_entry['compressed_size'];
3985 View Code Duplication
    while ($v_size != 0)
3986
    {
3987
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3988
      $v_buffer = @fread($this->zip_fd, $v_read_size);
3989
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
3990
      @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...
3991
      $v_size -= $v_read_size;
3992
    }
3993
3994
    // ----- Write gz file format footer
3995
    $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
3996
    @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...
3997
3998
    // ----- Close the temporary file
3999
    @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...
4000
4001
    // ----- Opening destination file
4002 View Code Duplication
    if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
4003
      $p_entry['status'] = "write_error";
4004
      return $v_result;
4005
    }
4006
4007
    // ----- Open the temporary gz file
4008 View Code Duplication
    if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
4009
      @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...
4010
      $p_entry['status'] = "read_error";
4011
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
4012
      return PclZip::errorCode();
4013
    }
4014
4015
4016
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4017
    $v_size = $p_entry['size'];
4018 View Code Duplication
    while ($v_size != 0) {
4019
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4020
      $v_buffer = @gzread($v_src_file, $v_read_size);
4021
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4022
      @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...
4023
      $v_size -= $v_read_size;
4024
    }
4025
    @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...
4026
    @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...
4027
4028
    // ----- Delete the temporary file
4029
    @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...
4030
    
4031
    // ----- Return
4032
    return $v_result;
4033
  }
4034
  // --------------------------------------------------------------------------------
4035
4036
  // --------------------------------------------------------------------------------
4037
  // Function : privExtractFileInOutput()
4038
  // Description :
4039
  // Parameters :
4040
  // Return Values :
4041
  // --------------------------------------------------------------------------------
4042
  function privExtractFileInOutput(&$p_entry, &$p_options)
4043
  {
4044
    $v_result=1;
4045
4046
    // ----- Read the file header
4047
    if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
4048
      return $v_result;
4049
    }
4050
4051
4052
    // ----- Check that the file header is coherent with $p_entry info
4053
    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4054
        // TBC
4055
    }
4056
4057
    // ----- Look for pre-extract callback
4058 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4059
4060
      // ----- Generate a local information
4061
      $v_local_header = array();
4062
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4063
4064
      // ----- Call the callback
4065
      // Here I do not use call_user_func() because I need to send a reference to the
4066
      // header.
4067
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4068
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4069
      if ($v_result == 0) {
4070
        // ----- Change the file status
4071
        $p_entry['status'] = "skipped";
4072
        $v_result = 1;
4073
      }
4074
4075
      // ----- Look for abort result
4076
      if ($v_result == 2) {
4077
        // ----- This status is internal and will be changed in 'skipped'
4078
        $p_entry['status'] = "aborted";
4079
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4080
      }
4081
4082
      // ----- Update the informations
4083
      // Only some fields can be modified
4084
      $p_entry['filename'] = $v_local_header['filename'];
4085
    }
4086
4087
    // ----- Trace
4088
4089
    // ----- Look if extraction should be done
4090
    if ($p_entry['status'] == 'ok') {
4091
4092
      // ----- Do the extraction (if not a folder)
4093
      if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4094
        // ----- Look for not compressed file
4095
        if ($p_entry['compressed_size'] == $p_entry['size']) {
4096
4097
          // ----- Read the file in a buffer (one shot)
4098
          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4099
4100
          // ----- Send the file to the output
4101
          echo $v_buffer;
4102
          unset($v_buffer);
4103
        }
4104
        else {
4105
4106
          // ----- Read the compressed file in a buffer (one shot)
4107
          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4108
          
4109
          // ----- Decompress the file
4110
          $v_file_content = gzinflate($v_buffer);
4111
          unset($v_buffer);
4112
4113
          // ----- Send the file to the output
4114
          echo $v_file_content;
4115
          unset($v_file_content);
4116
        }
4117
      }
4118
    }
4119
4120
	// ----- Change abort status
4121 View Code Duplication
	if ($p_entry['status'] == "aborted") {
4122
      $p_entry['status'] = "skipped";
4123
	}
4124
4125
    // ----- Look for post-extract callback
4126
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4127
4128
      // ----- Generate a local information
4129
      $v_local_header = array();
4130
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4131
4132
      // ----- Call the callback
4133
      // Here I do not use call_user_func() because I need to send a reference to the
4134
      // header.
4135
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_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)
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) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
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
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4183
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4184
      if ($v_result == 0) {
4185
        // ----- Change the file status
4186
        $p_entry['status'] = "skipped";
4187
        $v_result = 1;
4188
      }
4189
      
4190
      // ----- Look for abort result
4191
      if ($v_result == 2) {
4192
        // ----- This status is internal and will be changed in 'skipped'
4193
        $p_entry['status'] = "aborted";
4194
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4195
      }
4196
4197
      // ----- Update the informations
4198
      // Only some fields can be modified
4199
      $p_entry['filename'] = $v_local_header['filename'];
4200
    }
4201
4202
4203
    // ----- Look if extraction should be done
4204
    if ($p_entry['status'] == 'ok') {
4205
4206
      // ----- Do the extraction (if not a folder)
4207
      if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4208
        // ----- Look for not compressed file
4209
  //      if ($p_entry['compressed_size'] == $p_entry['size'])
4210
        if ($p_entry['compression'] == 0) {
4211
  
4212
          // ----- Reading the file
4213
          $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4214
        }
4215
        else {
4216
  
4217
          // ----- Reading the file
4218
          $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4219
          
4220
          // ----- Decompress the file
4221
          if (($p_string = @gzinflate($v_data)) === FALSE) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4222
              // TBC
4223
          }
4224
        }
4225
  
4226
        // ----- Trace
4227
      }
4228
      else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
4229
          // TBC : error : can not extract a folder in a string
4230
      }
4231
      
4232
    }
4233
4234
  	// ----- Change abort status
4235 View Code Duplication
  	if ($p_entry['status'] == "aborted") {
4236
        $p_entry['status'] = "skipped";
4237
  	}
4238
	
4239
    // ----- Look for post-extract callback
4240
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4241
4242
      // ----- Generate a local information
4243
      $v_local_header = array();
4244
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4245
      
4246
      // ----- Swap the content to header
4247
      $v_local_header['content'] = $p_string;
4248
      $p_string = '';
4249
4250
      // ----- Call the callback
4251
      // Here I do not use call_user_func() because I need to send a reference to the
4252
      // header.
4253
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4254
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4255
4256
      // ----- Swap back the content to header
4257
      $p_string = $v_local_header['content'];
4258
      unset($v_local_header['content']);
4259
4260
      // ----- Look for abort result
4261
      if ($v_result == 2) {
4262
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4263
      }
4264
    }
4265
4266
    // ----- Return
4267
    return $v_result;
4268
  }
4269
  // --------------------------------------------------------------------------------
4270
4271
  // --------------------------------------------------------------------------------
4272
  // Function : privReadFileHeader()
4273
  // Description :
4274
  // Parameters :
4275
  // Return Values :
4276
  // --------------------------------------------------------------------------------
4277
  function privReadFileHeader(&$p_header)
4278
  {
4279
    $v_result=1;
4280
4281
    // ----- Read the 4 bytes signature
4282
    $v_binary_data = @fread($this->zip_fd, 4);
4283
    $v_data = unpack('Vid', $v_binary_data);
4284
4285
    // ----- Check signature
4286
    if ($v_data['id'] != 0x04034b50)
4287
    {
4288
4289
      // ----- Error log
4290
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4291
4292
      // ----- Return
4293
      return PclZip::errorCode();
4294
    }
4295
4296
    // ----- Read the first 42 bytes of the header
4297
    $v_binary_data = fread($this->zip_fd, 26);
4298
4299
    // ----- Look for invalid block size
4300 View Code Duplication
    if (strlen($v_binary_data) != 26)
4301
    {
4302
      $p_header['filename'] = "";
4303
      $p_header['status'] = "invalid_header";
4304
4305
      // ----- Error log
4306
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4307
4308
      // ----- Return
4309
      return PclZip::errorCode();
4310
    }
4311
4312
    // ----- Extract the values
4313
    $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4314
4315
    // ----- Get filename
4316
    $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4317
4318
    // ----- Get extra_fields
4319
    if ($v_data['extra_len'] != 0) {
4320
      $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4321
    }
4322
    else {
4323
      $p_header['extra'] = '';
4324
    }
4325
4326
    // ----- Extract properties
4327
    $p_header['version_extracted'] = $v_data['version'];
4328
    $p_header['compression'] = $v_data['compression'];
4329
    $p_header['size'] = $v_data['size'];
4330
    $p_header['compressed_size'] = $v_data['compressed_size'];
4331
    $p_header['crc'] = $v_data['crc'];
4332
    $p_header['flag'] = $v_data['flag'];
4333
    $p_header['filename_len'] = $v_data['filename_len'];
4334
4335
    // ----- Recuperate date in UNIX format
4336
    $p_header['mdate'] = $v_data['mdate'];
4337
    $p_header['mtime'] = $v_data['mtime'];
4338
    if ($p_header['mdate'] && $p_header['mtime'])
4339
    {
4340
      // ----- Extract time
4341
      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4342
      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4343
      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4344
4345
      // ----- Extract date
4346
      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4347
      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4348
      $v_day = $p_header['mdate'] & 0x001F;
4349
4350
      // ----- Get UNIX date format
4351
      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4352
4353
    }
4354
    else
4355
    {
4356
      $p_header['mtime'] = time();
4357
    }
4358
4359
    // TBC
4360
    //for(reset($v_data); $key = key($v_data); next($v_data)) {
4361
    //}
4362
4363
    // ----- Set the stored filename
4364
    $p_header['stored_filename'] = $p_header['filename'];
4365
4366
    // ----- Set the status field
4367
    $p_header['status'] = "ok";
4368
4369
    // ----- Return
4370
    return $v_result;
4371
  }
4372
  // --------------------------------------------------------------------------------
4373
4374
  // --------------------------------------------------------------------------------
4375
  // Function : privReadCentralFileHeader()
4376
  // Description :
4377
  // Parameters :
4378
  // Return Values :
4379
  // --------------------------------------------------------------------------------
4380
  function privReadCentralFileHeader(&$p_header)
4381
  {
4382
    $v_result=1;
4383
4384
    // ----- Read the 4 bytes signature
4385
    $v_binary_data = @fread($this->zip_fd, 4);
4386
    $v_data = unpack('Vid', $v_binary_data);
4387
4388
    // ----- Check signature
4389
    if ($v_data['id'] != 0x02014b50)
4390
    {
4391
4392
      // ----- Error log
4393
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4394
4395
      // ----- Return
4396
      return PclZip::errorCode();
4397
    }
4398
4399
    // ----- Read the first 42 bytes of the header
4400
    $v_binary_data = fread($this->zip_fd, 42);
4401
4402
    // ----- Look for invalid block size
4403 View Code Duplication
    if (strlen($v_binary_data) != 42)
4404
    {
4405
      $p_header['filename'] = "";
4406
      $p_header['status'] = "invalid_header";
4407
4408
      // ----- Error log
4409
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4410
4411
      // ----- Return
4412
      return PclZip::errorCode();
4413
    }
4414
4415
    // ----- Extract the values
4416
    $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);
4417
4418
    // ----- Get filename
4419 View Code Duplication
    if ($p_header['filename_len'] != 0)
4420
      $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4421
    else
4422
      $p_header['filename'] = '';
4423
4424
    // ----- Get extra
4425 View Code Duplication
    if ($p_header['extra_len'] != 0)
4426
      $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4427
    else
4428
      $p_header['extra'] = '';
4429
4430
    // ----- Get comment
4431 View Code Duplication
    if ($p_header['comment_len'] != 0)
4432
      $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4433
    else
4434
      $p_header['comment'] = '';
4435
4436
    // ----- Extract properties
4437
4438
    // ----- Recuperate date in UNIX format
4439
    //if ($p_header['mdate'] && $p_header['mtime'])
4440
    // TBC : bug : this was ignoring time with 0/0/0
4441
    if (1)
4442
    {
4443
      // ----- Extract time
4444
      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4445
      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4446
      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4447
4448
      // ----- Extract date
4449
      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4450
      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4451
      $v_day = $p_header['mdate'] & 0x001F;
4452
4453
      // ----- Get UNIX date format
4454
      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4455
4456
    }
4457
    else
4458
    {
4459
      $p_header['mtime'] = time();
4460
    }
4461
4462
    // ----- Set the stored filename
4463
    $p_header['stored_filename'] = $p_header['filename'];
4464
4465
    // ----- Set default status to ok
4466
    $p_header['status'] = 'ok';
4467
4468
    // ----- Look if it is a directory
4469
    if (substr($p_header['filename'], -1) == '/') {
4470
      //$p_header['external'] = 0x41FF0010;
4471
      $p_header['external'] = 0x00000010;
4472
    }
4473
4474
4475
    // ----- Return
4476
    return $v_result;
4477
  }
4478
  // --------------------------------------------------------------------------------
4479
4480
  // --------------------------------------------------------------------------------
4481
  // Function : privCheckFileHeaders()
4482
  // Description :
4483
  // Parameters :
4484
  // Return Values :
4485
  //   1 on success,
4486
  //   0 on error;
4487
  // --------------------------------------------------------------------------------
4488
  function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4489
  {
4490
    $v_result=1;
4491
4492
  	// ----- Check the static values
4493
  	// TBC
4494
  	if ($p_local_header['filename'] != $p_central_header['filename']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4495
  	}
4496
  	if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4497
  	}
4498
  	if ($p_local_header['flag'] != $p_central_header['flag']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4499
  	}
4500
  	if ($p_local_header['compression'] != $p_central_header['compression']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4501
  	}
4502
  	if ($p_local_header['mtime'] != $p_central_header['mtime']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4503
  	}
4504
  	if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4505
  	}
4506
  
4507
  	// ----- Look for flag bit 3
4508
  	if (($p_local_header['flag'] & 8) == 8) {
4509
          $p_local_header['size'] = $p_central_header['size'];
4510
          $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4511
          $p_local_header['crc'] = $p_central_header['crc'];
4512
  	}
4513
4514
    // ----- Return
4515
    return $v_result;
4516
  }
4517
  // --------------------------------------------------------------------------------
4518
4519
  // --------------------------------------------------------------------------------
4520
  // Function : privReadEndCentralDir()
4521
  // Description :
4522
  // Parameters :
4523
  // Return Values :
4524
  // --------------------------------------------------------------------------------
4525
  function privReadEndCentralDir(&$p_central_dir)
4526
  {
4527
    $v_result=1;
4528
4529
    // ----- Go to the end of the zip file
4530
    $v_size = filesize($this->zipname);
4531
    @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...
4532 View Code Duplication
    if (@ftell($this->zip_fd) != $v_size)
4533
    {
4534
      // ----- Error log
4535
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4536
4537
      // ----- Return
4538
      return PclZip::errorCode();
4539
    }
4540
4541
    // ----- First try : look if this is an archive with no commentaries (most of the time)
4542
    // in this case the end of central dir is at 22 bytes of the file end
4543
    $v_found = 0;
4544
    if ($v_size > 26) {
4545
      @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...
4546 View Code Duplication
      if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4547
      {
4548
        // ----- Error log
4549
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4550
4551
        // ----- Return
4552
        return PclZip::errorCode();
4553
      }
4554
4555
      // ----- Read for bytes
4556
      $v_binary_data = @fread($this->zip_fd, 4);
4557
      $v_data = @unpack('Vid', $v_binary_data);
4558
4559
      // ----- Check signature
4560
      if ($v_data['id'] == 0x06054b50) {
4561
        $v_found = 1;
4562
      }
4563
4564
      $v_pos = ftell($this->zip_fd);
4565
    }
4566
4567
    // ----- Go back to the maximum possible size of the Central Dir End Record
4568
    if (!$v_found) {
4569
      $v_maximum_size = 65557; // 0xFFFF + 22;
4570
      if ($v_maximum_size > $v_size)
4571
        $v_maximum_size = $v_size;
4572
      @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...
4573 View Code Duplication
      if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4574
      {
4575
        // ----- Error log
4576
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4577
4578
        // ----- Return
4579
        return PclZip::errorCode();
4580
      }
4581
4582
      // ----- Read byte per byte in order to find the signature
4583
      $v_pos = ftell($this->zip_fd);
4584
      $v_bytes = 0x00000000;
4585
      while ($v_pos < $v_size)
4586
      {
4587
        // ----- Read a byte
4588
        $v_byte = @fread($this->zip_fd, 1);
4589
4590
        // -----  Add the byte
4591
        //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
4592
        // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number 
4593
        // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. 
4594
        $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); 
4595
4596
        // ----- Compare the bytes
4597
        if ($v_bytes == 0x504b0506)
4598
        {
4599
          $v_pos++;
4600
          break;
4601
        }
4602
4603
        $v_pos++;
4604
      }
4605
4606
      // ----- Look if not found end of central dir
4607
      if ($v_pos == $v_size)
4608
      {
4609
4610
        // ----- Error log
4611
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4612
4613
        // ----- Return
4614
        return PclZip::errorCode();
4615
      }
4616
    }
4617
4618
    // ----- Read the first 18 bytes of the header
4619
    $v_binary_data = fread($this->zip_fd, 18);
4620
4621
    // ----- Look for invalid block size
4622 View Code Duplication
    if (strlen($v_binary_data) != 18)
4623
    {
4624
4625
      // ----- Error log
4626
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4627
4628
      // ----- Return
4629
      return PclZip::errorCode();
4630
    }
4631
4632
    // ----- Extract the values
4633
    $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4634
4635
    // ----- Check the global size
4636
    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...
4637
4638
	  // ----- Removed in release 2.2 see readme file
4639
	  // The check of the file size is a little too strict.
4640
	  // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4641
	  // While decrypted, zip has training 0 bytes
4642
	  if (0) {
4643
      // ----- Error log
4644
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4645
	                       'The central dir is not at the end of the archive.'
4646
						   .' Some trailing bytes exists after the archive.');
4647
4648
      // ----- Return
4649
      return PclZip::errorCode();
4650
	  }
4651
    }
4652
4653
    // ----- Get comment
4654
    if ($v_data['comment_size'] != 0) {
4655
      $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4656
    }
4657
    else
4658
      $p_central_dir['comment'] = '';
4659
4660
    $p_central_dir['entries'] = $v_data['entries'];
4661
    $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4662
    $p_central_dir['offset'] = $v_data['offset'];
4663
    $p_central_dir['size'] = $v_data['size'];
4664
    $p_central_dir['disk'] = $v_data['disk'];
4665
    $p_central_dir['disk_start'] = $v_data['disk_start'];
4666
4667
    // TBC
4668
    //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4669
    //}
4670
4671
    // ----- Return
4672
    return $v_result;
4673
  }
4674
  // --------------------------------------------------------------------------------
4675
4676
  // --------------------------------------------------------------------------------
4677
  // Function : privDeleteByRule()
4678
  // Description :
4679
  // Parameters :
4680
  // Return Values :
4681
  // --------------------------------------------------------------------------------
4682
  function privDeleteByRule(&$p_result_list, &$p_options)
4683
  {
4684
    $v_result=1;
4685
    $v_list_detail = array();
4686
4687
    // ----- Open the zip file
4688
    if (($v_result=$this->privOpenFd('rb')) != 1)
4689
    {
4690
      // ----- Return
4691
      return $v_result;
4692
    }
4693
4694
    // ----- Read the central directory informations
4695
    $v_central_dir = array();
4696
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4697
    {
4698
      $this->privCloseFd();
4699
      return $v_result;
4700
    }
4701
4702
    // ----- Go to beginning of File
4703
    @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...
4704
4705
    // ----- Scan all the files
4706
    // ----- Start at beginning of Central Dir
4707
    $v_pos_entry = $v_central_dir['offset'];
4708
    @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...
4709 View Code Duplication
    if (@fseek($this->zip_fd, $v_pos_entry))
4710
    {
4711
      // ----- Close the zip file
4712
      $this->privCloseFd();
4713
4714
      // ----- Error log
4715
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4716
4717
      // ----- Return
4718
      return PclZip::errorCode();
4719
    }
4720
4721
    // ----- Read each entry
4722
    $v_header_list = array();
4723
    $j_start = 0;
4724
    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4725
    {
4726
4727
      // ----- Read the file header
4728
      $v_header_list[$v_nb_extracted] = array();
4729
      if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4730
      {
4731
        // ----- Close the zip file
4732
        $this->privCloseFd();
4733
4734
        return $v_result;
4735
      }
4736
4737
4738
      // ----- Store the index
4739
      $v_header_list[$v_nb_extracted]['index'] = $i;
4740
4741
      // ----- Look for the specific extract rules
4742
      $v_found = false;
4743
4744
      // ----- Look for extract by name rule
4745
      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
4746
          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4747
4748
          // ----- Look if the filename is in the list
4749
          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4750
4751
              // ----- Look for a directory
4752
              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4753
4754
                  // ----- Look if the directory is in the filename path
4755
                  if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4756
                      && (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])) {
4757
                      $v_found = true;
4758
                  }
4759
                  elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4760
                          && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4761
                      $v_found = true;
4762
                  }
4763
              }
4764
              // ----- Look for a filename
4765
              elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4766
                  $v_found = true;
4767
              }
4768
          }
4769
      }
4770
4771
      // ----- Look for extract by ereg rule
4772
      // ereg() is deprecated with PHP 5.3
4773
      /*
4774
      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
4775
               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4776
4777
          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4778
              $v_found = true;
4779
          }
4780
      }
4781
      */
4782
4783
      // ----- Look for extract by preg rule
4784 View Code Duplication
      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
4785
               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4786
4787
          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4788
              $v_found = true;
4789
          }
4790
      }
4791
4792
      // ----- Look for extract by index rule
4793
      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4794
               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4795
4796
          // ----- Look if the index is in the list
4797
          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4798
4799
              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4800
                  $v_found = true;
4801
              }
4802
              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4803
                  $j_start = $j+1;
4804
              }
4805
4806
              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4807
                  break;
4808
              }
4809
          }
4810
      }
4811
      else {
4812
      	$v_found = true;
4813
      }
4814
4815
      // ----- Look for deletion
4816
      if ($v_found)
4817
      {
4818
        unset($v_header_list[$v_nb_extracted]);
4819
      }
4820
      else
4821
      {
4822
        $v_nb_extracted++;
4823
      }
4824
    }
4825
4826
    // ----- Look if something need to be deleted
4827
    if ($v_nb_extracted > 0) {
4828
4829
        // ----- Creates a temporay file
4830
        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4831
4832
        // ----- Creates a temporary zip archive
4833
        $v_temp_zip = new PclZip($v_zip_temp_name);
4834
4835
        // ----- Open the temporary zip file in write mode
4836
        if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4837
            $this->privCloseFd();
4838
4839
            // ----- Return
4840
            return $v_result;
4841
        }
4842
4843
        // ----- Look which file need to be kept
4844
        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...
4845
4846
            // ----- Calculate the position of the header
4847
            @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...
4848
            if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
4849
                // ----- Close the zip file
4850
                $this->privCloseFd();
4851
                $v_temp_zip->privCloseFd();
4852
                @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...
4853
4854
                // ----- Error log
4855
                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4856
4857
                // ----- Return
4858
                return PclZip::errorCode();
4859
            }
4860
4861
            // ----- Read the file header
4862
            $v_local_header = array();
4863
            if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4864
                // ----- Close the zip file
4865
                $this->privCloseFd();
4866
                $v_temp_zip->privCloseFd();
4867
                @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...
4868
4869
                // ----- Return
4870
                return $v_result;
4871
            }
4872
            
4873
            // ----- Check that local file header is same as central file header
4874
            if ($this->privCheckFileHeaders($v_local_header,
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
4875
			                                $v_header_list[$i]) != 1) {
4876
                // TBC
4877
            }
4878
            unset($v_local_header);
4879
4880
            // ----- Write the file header
4881 View Code Duplication
            if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4882
                // ----- Close the zip file
4883
                $this->privCloseFd();
4884
                $v_temp_zip->privCloseFd();
4885
                @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...
4886
4887
                // ----- Return
4888
                return $v_result;
4889
            }
4890
4891
            // ----- Read/write the data block
4892
            if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4893
                // ----- Close the zip file
4894
                $this->privCloseFd();
4895
                $v_temp_zip->privCloseFd();
4896
                @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...
4897
4898
                // ----- Return
4899
                return $v_result;
4900
            }
4901
        }
4902
4903
        // ----- Store the offset of the central dir
4904
        $v_offset = @ftell($v_temp_zip->zip_fd);
4905
4906
        // ----- Re-Create the Central Dir files header
4907
        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...
4908
            // ----- Create the file header
4909 View Code Duplication
            if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4910
                $v_temp_zip->privCloseFd();
4911
                $this->privCloseFd();
4912
                @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...
4913
4914
                // ----- Return
4915
                return $v_result;
4916
            }
4917
4918
            // ----- Transform the header to a 'usable' info
4919
            $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4920
        }
4921
4922
4923
        // ----- Zip file comment
4924
        $v_comment = '';
4925
        if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4926
          $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4927
        }
4928
4929
        // ----- Calculate the size of the central header
4930
        $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4931
4932
        // ----- Create the central dir footer
4933
        if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4934
            // ----- Reset the file list
4935
            unset($v_header_list);
4936
            $v_temp_zip->privCloseFd();
4937
            $this->privCloseFd();
4938
            @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...
4939
4940
            // ----- Return
4941
            return $v_result;
4942
        }
4943
4944
        // ----- Close
4945
        $v_temp_zip->privCloseFd();
4946
        $this->privCloseFd();
4947
4948
        // ----- Delete the zip file
4949
        // TBC : I should test the result ...
4950
        @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...
4951
4952
        // ----- Rename the temporary file
4953
        // TBC : I should test the result ...
4954
        //@rename($v_zip_temp_name, $this->zipname);
4955
        PclZipUtilRename($v_zip_temp_name, $this->zipname);
4956
    
4957
        // ----- Destroy the temporary archive
4958
        unset($v_temp_zip);
4959
    }
4960
    
4961
    // ----- Remove every files : reset the file
4962
    else if ($v_central_dir['entries'] != 0) {
4963
        $this->privCloseFd();
4964
4965
        if (($v_result = $this->privOpenFd('wb')) != 1) {
4966
          return $v_result;
4967
        }
4968
4969
        if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4970
          return $v_result;
4971
        }
4972
4973
        $this->privCloseFd();
4974
    }
4975
4976
    // ----- Return
4977
    return $v_result;
4978
  }
4979
  // --------------------------------------------------------------------------------
4980
4981
  // --------------------------------------------------------------------------------
4982
  // Function : privDirCheck()
4983
  // Description :
4984
  //   Check if a directory exists, if not it creates it and all the parents directory
4985
  //   which may be useful.
4986
  // Parameters :
4987
  //   $p_dir : Directory path to check.
4988
  // Return Values :
4989
  //    1 : OK
4990
  //   -1 : Unable to create directory
4991
  // --------------------------------------------------------------------------------
4992
  function privDirCheck($p_dir, $p_is_dir=false)
4993
  {
4994
    $v_result = 1;
4995
4996
4997
    // ----- Remove the final '/'
4998
    if (($p_is_dir) && (substr($p_dir, -1)=='/'))
4999
    {
5000
      $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
5001
    }
5002
5003
    // ----- Check the directory availability
5004
    if ((is_dir($p_dir)) || ($p_dir == ""))
5005
    {
5006
      return 1;
5007
    }
5008
5009
    // ----- Extract parent directory
5010
    $p_parent_dir = dirname($p_dir);
5011
5012
    // ----- Just a check
5013
    if ($p_parent_dir != $p_dir)
5014
    {
5015
      // ----- Look for parent directory
5016
      if ($p_parent_dir != "")
5017
      {
5018
        if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
5019
        {
5020
          return $v_result;
5021
        }
5022
      }
5023
    }
5024
5025
    // ----- Create the directory
5026
    if (!@mkdir($p_dir, 0777))
5027
    {
5028
      // ----- Error log
5029
      PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
5030
5031
      // ----- Return
5032
      return PclZip::errorCode();
5033
    }
5034
5035
    // ----- Return
5036
    return $v_result;
5037
  }
5038
  // --------------------------------------------------------------------------------
5039
5040
  // --------------------------------------------------------------------------------
5041
  // Function : privMerge()
5042
  // Description :
5043
  //   If $p_archive_to_add does not exist, the function exit with a success result.
5044
  // Parameters :
5045
  // Return Values :
5046
  // --------------------------------------------------------------------------------
5047
  function privMerge(&$p_archive_to_add)
5048
  {
5049
    $v_result=1;
5050
5051
    // ----- Look if the archive_to_add exists
5052
    if (!is_file($p_archive_to_add->zipname))
5053
    {
5054
5055
      // ----- Nothing to merge, so merge is a success
5056
      $v_result = 1;
5057
5058
      // ----- Return
5059
      return $v_result;
5060
    }
5061
5062
    // ----- Look if the archive exists
5063
    if (!is_file($this->zipname))
5064
    {
5065
5066
      // ----- Do a duplicate
5067
      $v_result = $this->privDuplicate($p_archive_to_add->zipname);
5068
5069
      // ----- Return
5070
      return $v_result;
5071
    }
5072
5073
    // ----- Open the zip file
5074
    if (($v_result=$this->privOpenFd('rb')) != 1)
5075
    {
5076
      // ----- Return
5077
      return $v_result;
5078
    }
5079
5080
    // ----- Read the central directory informations
5081
    $v_central_dir = array();
5082
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
5083
    {
5084
      $this->privCloseFd();
5085
      return $v_result;
5086
    }
5087
5088
    // ----- Go to beginning of File
5089
    @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...
5090
5091
    // ----- Open the archive_to_add file
5092
    if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
5093
    {
5094
      $this->privCloseFd();
5095
5096
      // ----- Return
5097
      return $v_result;
5098
    }
5099
5100
    // ----- Read the central directory informations
5101
    $v_central_dir_to_add = array();
5102
    if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5103
    {
5104
      $this->privCloseFd();
5105
      $p_archive_to_add->privCloseFd();
5106
5107
      return $v_result;
5108
    }
5109
5110
    // ----- Go to beginning of File
5111
    @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...
5112
5113
    // ----- Creates a temporay file
5114
    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
5115
5116
    // ----- Open the temporary file in write mode
5117
    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
5118
    {
5119
      $this->privCloseFd();
5120
      $p_archive_to_add->privCloseFd();
5121
5122
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
5123
5124
      // ----- Return
5125
      return PclZip::errorCode();
5126
    }
5127
5128
    // ----- Copy the files from the archive to the temporary file
5129
    // TBC : Here I should better append the file and go back to erase the central dir
5130
    $v_size = $v_central_dir['offset'];
5131
    while ($v_size != 0)
5132
    {
5133
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5134
      $v_buffer = fread($this->zip_fd, $v_read_size);
5135
      @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...
5136
      $v_size -= $v_read_size;
5137
    }
5138
5139
    // ----- Copy the files from the archive_to_add into the temporary file
5140
    $v_size = $v_central_dir_to_add['offset'];
5141
    while ($v_size != 0)
5142
    {
5143
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5144
      $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
5145
      @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...
5146
      $v_size -= $v_read_size;
5147
    }
5148
5149
    // ----- Store the offset of the central dir
5150
    $v_offset = @ftell($v_zip_temp_fd);
5151
5152
    // ----- Copy the block of file headers from the old archive
5153
    $v_size = $v_central_dir['size'];
5154 View Code Duplication
    while ($v_size != 0)
5155
    {
5156
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5157
      $v_buffer = @fread($this->zip_fd, $v_read_size);
5158
      @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...
5159
      $v_size -= $v_read_size;
5160
    }
5161
5162
    // ----- Copy the block of file headers from the archive_to_add
5163
    $v_size = $v_central_dir_to_add['size'];
5164 View Code Duplication
    while ($v_size != 0)
5165
    {
5166
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5167
      $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
5168
      @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...
5169
      $v_size -= $v_read_size;
5170
    }
5171
5172
    // ----- Merge the file comments
5173
    $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
5174
5175
    // ----- Calculate the size of the (new) central header
5176
    $v_size = @ftell($v_zip_temp_fd)-$v_offset;
5177
5178
    // ----- Swap the file descriptor
5179
    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
5180
    // the following methods on the temporary fil and not the real archive fd
5181
    $v_swap = $this->zip_fd;
5182
    $this->zip_fd = $v_zip_temp_fd;
5183
    $v_zip_temp_fd = $v_swap;
5184
5185
    // ----- Create the central dir footer
5186
    if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
5187
    {
5188
      $this->privCloseFd();
5189
      $p_archive_to_add->privCloseFd();
5190
      @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...
5191
      $this->zip_fd = null;
5192
5193
      // ----- Reset the file list
5194
      unset($v_header_list);
5195
5196
      // ----- Return
5197
      return $v_result;
5198
    }
5199
5200
    // ----- Swap back the file descriptor
5201
    $v_swap = $this->zip_fd;
5202
    $this->zip_fd = $v_zip_temp_fd;
5203
    $v_zip_temp_fd = $v_swap;
5204
5205
    // ----- Close
5206
    $this->privCloseFd();
5207
    $p_archive_to_add->privCloseFd();
5208
5209
    // ----- Close the temporary file
5210
    @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...
5211
5212
    // ----- Delete the zip file
5213
    // TBC : I should test the result ...
5214
    @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...
5215
5216
    // ----- Rename the temporary file
5217
    // TBC : I should test the result ...
5218
    //@rename($v_zip_temp_name, $this->zipname);
5219
    PclZipUtilRename($v_zip_temp_name, $this->zipname);
5220
5221
    // ----- Return
5222
    return $v_result;
5223
  }
5224
  // --------------------------------------------------------------------------------
5225
5226
  // --------------------------------------------------------------------------------
5227
  // Function : privDuplicate()
5228
  // Description :
5229
  // Parameters :
5230
  // Return Values :
5231
  // --------------------------------------------------------------------------------
5232
  function privDuplicate($p_archive_filename)
5233
  {
5234
    $v_result=1;
5235
5236
    // ----- Look if the $p_archive_filename exists
5237
    if (!is_file($p_archive_filename))
5238
    {
5239
5240
      // ----- Nothing to duplicate, so duplicate is a success.
5241
      $v_result = 1;
5242
5243
      // ----- Return
5244
      return $v_result;
5245
    }
5246
5247
    // ----- Open the zip file
5248
    if (($v_result=$this->privOpenFd('wb')) != 1)
5249
    {
5250
      // ----- Return
5251
      return $v_result;
5252
    }
5253
5254
    // ----- Open the temporary file in write mode
5255 View Code Duplication
    if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
5256
    {
5257
      $this->privCloseFd();
5258
5259
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
5260
5261
      // ----- Return
5262
      return PclZip::errorCode();
5263
    }
5264
5265
    // ----- Copy the files from the archive to the temporary file
5266
    // TBC : Here I should better append the file and go back to erase the central dir
5267
    $v_size = filesize($p_archive_filename);
5268
    while ($v_size != 0)
5269
    {
5270
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5271
      $v_buffer = fread($v_zip_temp_fd, $v_read_size);
5272
      @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...
5273
      $v_size -= $v_read_size;
5274
    }
5275
5276
    // ----- Close
5277
    $this->privCloseFd();
5278
5279
    // ----- Close the temporary file
5280
    @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...
5281
5282
    // ----- Return
5283
    return $v_result;
5284
  }
5285
  // --------------------------------------------------------------------------------
5286
5287
  // --------------------------------------------------------------------------------
5288
  // Function : privErrorLog()
5289
  // Description :
5290
  // Parameters :
5291
  // --------------------------------------------------------------------------------
5292
  function privErrorLog($p_error_code=0, $p_error_string='')
5293
  {
5294
    if (PCLZIP_ERROR_EXTERNAL == 1) {
5295
      PclError($p_error_code, $p_error_string);
5296
    }
5297
    else {
5298
      $this->error_code = $p_error_code;
5299
      $this->error_string = $p_error_string;
5300
    }
5301
  }
5302
  // --------------------------------------------------------------------------------
5303
5304
  // --------------------------------------------------------------------------------
5305
  // Function : privErrorReset()
5306
  // Description :
5307
  // Parameters :
5308
  // --------------------------------------------------------------------------------
5309
  function privErrorReset()
5310
  {
5311
    if (PCLZIP_ERROR_EXTERNAL == 1) {
5312
      PclErrorReset();
5313
    }
5314
    else {
5315
      $this->error_code = 0;
5316
      $this->error_string = '';
5317
    }
5318
  }
5319
  // --------------------------------------------------------------------------------
5320
5321
  // --------------------------------------------------------------------------------
5322
  // Function : privDisableMagicQuotes()
5323
  // Description :
5324
  // Parameters :
5325
  // Return Values :
5326
  // --------------------------------------------------------------------------------
5327 View Code Duplication
  function privDisableMagicQuotes()
5328
  {
5329
    $v_result=1;
5330
5331
    // ----- Look if function exists
5332
    if (   (!function_exists("get_magic_quotes_runtime"))
5333
	    || (!function_exists("set_magic_quotes_runtime"))) {
5334
      return $v_result;
5335
	}
5336
5337
    // ----- Look if already done
5338
    if ($this->magic_quotes_status != -1) {
5339
      return $v_result;
5340
	}
5341
5342
	// ----- Get and memorize the magic_quote value
5343
	$this->magic_quotes_status = @get_magic_quotes_runtime();
5344
5345
	// ----- Disable magic_quotes
5346
	if ($this->magic_quotes_status == 1) {
5347
	  @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...
5348
	}
5349
5350
    // ----- Return
5351
    return $v_result;
5352
  }
5353
  // --------------------------------------------------------------------------------
5354
5355
  // --------------------------------------------------------------------------------
5356
  // Function : privSwapBackMagicQuotes()
5357
  // Description :
5358
  // Parameters :
5359
  // Return Values :
5360
  // --------------------------------------------------------------------------------
5361 View Code Duplication
  function privSwapBackMagicQuotes()
5362
  {
5363
    $v_result=1;
5364
5365
    // ----- Look if function exists
5366
    if (   (!function_exists("get_magic_quotes_runtime"))
5367
	    || (!function_exists("set_magic_quotes_runtime"))) {
5368
      return $v_result;
5369
	}
5370
5371
    // ----- Look if something to do
5372
    if ($this->magic_quotes_status != -1) {
5373
      return $v_result;
5374
	}
5375
5376
	// ----- Swap back magic_quotes
5377
	if ($this->magic_quotes_status == 1) {
5378
  	  @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...
5379
	}
5380
5381
    // ----- Return
5382
    return $v_result;
5383
  }
5384
  // --------------------------------------------------------------------------------
5385
5386
  }
5387
  // End of class
5388
  // --------------------------------------------------------------------------------
5389
5390
  // --------------------------------------------------------------------------------
5391
  // Function : PclZipUtilPathReduction()
5392
  // Description :
5393
  // Parameters :
5394
  // Return Values :
5395
  // --------------------------------------------------------------------------------
5396
  function PclZipUtilPathReduction($p_dir)
5397
  {
5398
    $v_result = "";
5399
5400
    // ----- Look for not empty path
5401
    if ($p_dir != "") {
5402
      // ----- Explode path by directory names
5403
      $v_list = explode("/", $p_dir);
5404
5405
      // ----- Study directories from last to first
5406
      $v_skip = 0;
5407
      for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5408
        // ----- Look for current path
5409
        if ($v_list[$i] == ".") {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
5410
          // ----- Ignore this directory
5411
          // Should be the first $i=0, but no check is done
5412
        }
5413
        else if ($v_list[$i] == "..") {
5414
		  $v_skip++;
5415
        }
5416
        else if ($v_list[$i] == "") {
5417
		  // ----- First '/' i.e. root slash
5418
		  if ($i == 0) {
5419
            $v_result = "/".$v_result;
5420
		    if ($v_skip > 0) {
5421
		        // ----- It is an invalid path, so the path is not modified
5422
		        // TBC
5423
		        $v_result = $p_dir;
5424
                $v_skip = 0;
5425
		    }
5426
		  }
5427
		  // ----- Last '/' i.e. indicates a directory
5428
		  else if ($i == (sizeof($v_list)-1)) {
5429
            $v_result = $v_list[$i];
5430
		  }
5431
		  // ----- Double '/' inside the path
5432
		  else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
5433
            // ----- Ignore only the double '//' in path,
5434
            // but not the first and last '/'
5435
		  }
5436
        }
5437
        else {
5438
		  // ----- Look for item to skip
5439
		  if ($v_skip > 0) {
5440
		    $v_skip--;
5441
		  }
5442
		  else {
5443
            $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5444
		  }
5445
        }
5446
      }
5447
      
5448
      // ----- Look for skip
5449
      if ($v_skip > 0) {
5450
        while ($v_skip > 0) {
5451
            $v_result = '../'.$v_result;
5452
            $v_skip--;
5453
        }
5454
      }
5455
    }
5456
5457
    // ----- Return
5458
    return $v_result;
5459
  }
5460
  // --------------------------------------------------------------------------------
5461
5462
  // --------------------------------------------------------------------------------
5463
  // Function : PclZipUtilPathInclusion()
5464
  // Description :
5465
  //   This function indicates if the path $p_path is under the $p_dir tree. Or,
5466
  //   said in an other way, if the file or sub-dir $p_path is inside the dir
5467
  //   $p_dir.
5468
  //   The function indicates also if the path is exactly the same as the dir.
5469
  //   This function supports path with duplicated '/' like '//', but does not
5470
  //   support '.' or '..' statements.
5471
  // Parameters :
5472
  // Return Values :
5473
  //   0 if $p_path is not inside directory $p_dir
5474
  //   1 if $p_path is inside directory $p_dir
5475
  //   2 if $p_path is exactly the same as $p_dir
5476
  // --------------------------------------------------------------------------------
5477
  function PclZipUtilPathInclusion($p_dir, $p_path)
5478
  {
5479
    $v_result = 1;
5480
    
5481
    // ----- Look for path beginning by ./
5482 View Code Duplication
    if (   ($p_dir == '.')
5483
        || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
5484
      $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
5485
    }
5486 View Code Duplication
    if (   ($p_path == '.')
5487
        || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
5488
      $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
5489
    }
5490
5491
    // ----- Explode dir and path by directory separator
5492
    $v_list_dir = explode("/", $p_dir);
5493
    $v_list_dir_size = sizeof($v_list_dir);
5494
    $v_list_path = explode("/", $p_path);
5495
    $v_list_path_size = sizeof($v_list_path);
5496
5497
    // ----- Study directories paths
5498
    $i = 0;
5499
    $j = 0;
5500
    while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5501
5502
      // ----- Look for empty dir (path reduction)
5503
      if ($v_list_dir[$i] == '') {
5504
        $i++;
5505
        continue;
5506
      }
5507
      if ($v_list_path[$j] == '') {
5508
        $j++;
5509
        continue;
5510
      }
5511
5512
      // ----- Compare the items
5513
      if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {
5514
        $v_result = 0;
5515
      }
5516
5517
      // ----- Next items
5518
      $i++;
5519
      $j++;
5520
    }
5521
5522
    // ----- Look if everything seems to be the same
5523
    if ($v_result) {
5524
      // ----- Skip all the empty items
5525
      while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5526
      while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5527
5528
      if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5529
        // ----- There are exactly the same
5530
        $v_result = 2;
5531
      }
5532
      else if ($i < $v_list_dir_size) {
5533
        // ----- The path is shorter than the dir
5534
        $v_result = 0;
5535
      }
5536
    }
5537
5538
    // ----- Return
5539
    return $v_result;
5540
  }
5541
  // --------------------------------------------------------------------------------
5542
5543
  // --------------------------------------------------------------------------------
5544
  // Function : PclZipUtilCopyBlock()
5545
  // Description :
5546
  // Parameters :
5547
  //   $p_mode : read/write compression mode
5548
  //             0 : src & dest normal
5549
  //             1 : src gzip, dest normal
5550
  //             2 : src normal, dest gzip
5551
  //             3 : src & dest gzip
5552
  // Return Values :
5553
  // --------------------------------------------------------------------------------
5554
  function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5555
  {
5556
    $v_result = 1;
5557
5558
    if ($p_mode==0)
5559
    {
5560 View Code Duplication
      while ($p_size != 0)
5561
      {
5562
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5563
        $v_buffer = @fread($p_src, $v_read_size);
5564
        @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...
5565
        $p_size -= $v_read_size;
5566
      }
5567
    }
5568
    else if ($p_mode==1)
5569
    {
5570 View Code Duplication
      while ($p_size != 0)
5571
      {
5572
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5573
        $v_buffer = @gzread($p_src, $v_read_size);
5574
        @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...
5575
        $p_size -= $v_read_size;
5576
      }
5577
    }
5578
    else if ($p_mode==2)
5579
    {
5580 View Code Duplication
      while ($p_size != 0)
5581
      {
5582
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5583
        $v_buffer = @fread($p_src, $v_read_size);
5584
        @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...
5585
        $p_size -= $v_read_size;
5586
      }
5587
    }
5588
    else if ($p_mode==3)
5589
    {
5590 View Code Duplication
      while ($p_size != 0)
5591
      {
5592
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5593
        $v_buffer = @gzread($p_src, $v_read_size);
5594
        @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...
5595
        $p_size -= $v_read_size;
5596
      }
5597
    }
5598
5599
    // ----- Return
5600
    return $v_result;
5601
  }
5602
  // --------------------------------------------------------------------------------
5603
5604
  // --------------------------------------------------------------------------------
5605
  // Function : PclZipUtilRename()
5606
  // Description :
5607
  //   This function tries to do a simple rename() function. If it fails, it
5608
  //   tries to copy the $p_src file in a new $p_dest file and then unlink the
5609
  //   first one.
5610
  // Parameters :
5611
  //   $p_src : Old filename
5612
  //   $p_dest : New filename
5613
  // Return Values :
5614
  //   1 on success, 0 on failure.
5615
  // --------------------------------------------------------------------------------
5616
  function PclZipUtilRename($p_src, $p_dest)
5617
  {
5618
    $v_result = 1;
5619
5620
    // ----- Try to rename the files
5621
    if (!@rename($p_src, $p_dest)) {
5622
5623
      // ----- Try to copy & unlink the src
5624
      if (!@copy($p_src, $p_dest)) {
5625
        $v_result = 0;
5626
      }
5627
      else if (!@unlink($p_src)) {
5628
        $v_result = 0;
5629
      }
5630
    }
5631
5632
    // ----- Return
5633
    return $v_result;
5634
  }
5635
  // --------------------------------------------------------------------------------
5636
5637
  // --------------------------------------------------------------------------------
5638
  // Function : PclZipUtilOptionText()
5639
  // Description :
5640
  //   Translate option value in text. Mainly for debug purpose.
5641
  // Parameters :
5642
  //   $p_option : the option value.
5643
  // Return Values :
5644
  //   The option text value.
5645
  // --------------------------------------------------------------------------------
5646
  function PclZipUtilOptionText($p_option)
5647
  {
5648
    
5649
    $v_list = get_defined_constants();
5650
    for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5651
	    $v_prefix = substr($v_key, 0, 10);
5652
	    if ((   ($v_prefix == 'PCLZIP_OPT')
5653
           || ($v_prefix == 'PCLZIP_CB_')
5654
           || ($v_prefix == 'PCLZIP_ATT'))
5655
	        && ($v_list[$v_key] == $p_option)) {
5656
        return $v_key;
5657
	    }
5658
    }
5659
    
5660
    $v_result = 'Unknown';
5661
5662
    return $v_result;
5663
  }
5664
  // --------------------------------------------------------------------------------
5665
5666
  // --------------------------------------------------------------------------------
5667
  // Function : PclZipUtilTranslateWinPath()
5668
  // Description :
5669
  //   Translate windows path by replacing '\' by '/' and optionally removing
5670
  //   drive letter.
5671
  // Parameters :
5672
  //   $p_path : path to translate.
5673
  //   $p_remove_disk_letter : true | false
5674
  // Return Values :
5675
  //   The path translated.
5676
  // --------------------------------------------------------------------------------
5677
  function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
5678
  {
5679
    if (stristr(php_uname(), 'windows')) {
5680
      // ----- Look for potential disk letter
5681
      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...
5682
          $p_path = substr($p_path, $v_position+1);
5683
      }
5684
      // ----- Change potential windows directory separator
5685
      if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5686
          $p_path = strtr($p_path, '\\', '/');
5687
      }
5688
    }
5689
    return $p_path;
5690
  }
5691
  // --------------------------------------------------------------------------------
5692
5693
5694
?>
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...
5695