Completed
Push — 1.10.x ( 484d85...fbe198 )
by Julito
35:25
created

PclZip::__construct()   A

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
nc 2
nop 1
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package chamilo.include
4
 */
5
/**
6
 * Code
7
 */
8
// --------------------------------------------------------------------------------
9
// PhpConcept Library - Zip Module 2.8.2
10
// --------------------------------------------------------------------------------
11
// License GNU/LGPL - Vincent Blavet - August 2009
12
// http://www.phpconcept.net
13
// --------------------------------------------------------------------------------
14
//
15
// Presentation :
16
//   PclZip is a PHP library that manage ZIP archives.
17
//   So far tests show that archives generated by PclZip are readable by
18
//   WinZip application and other tools.
19
//
20
// Description :
21
//   See readme.txt and http://www.phpconcept.net
22
//
23
// Warning :
24
//   This library and the associated files are non commercial, non professional
25
//   work.
26
//   It should not have unexpected results. However if any damage is caused by
27
//   this software the author can not be responsible.
28
//   The use of this software is at the risk of the user.
29
//
30
// --------------------------------------------------------------------------------
31
// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
32
// --------------------------------------------------------------------------------
33
34
// --------------------------------------------------------------------------------
35
// A patch about the renamed function gzopen() as gzopen64()
36
// in Ubuntu Karmic Koala 9.10 (php5 5.2.10.dfsg.1-2ubuntu6).
37
// http://dokeoslead.wordpress.com/2009/09/30/pclzip-and-gzopen64/
38
// https://bugs.launchpad.net/ubuntu/+source/php5/+bug/451405
39
// http://php.net/manual/en/function.gzopen.php
40
// --------------------------------------------------------------------------------
41
if (!function_exists('gzopen') && function_exists('gzopen64')) {
42
	function gzopen($filename, $mode, $use_include_path = 0) {
43
		return gzopen64($filename, $mode, $use_include_path);
44
	}
45
}
46
// --------------------------------------------------------------------------------
47
48
  // ----- Constants
49
  if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
50
    define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
51
  }
52
53
  // ----- File list separator
54
  // In version 1.x of PclZip, the separator for file list is a space
55
  // (which is not a very smart choice, specifically for windows paths !).
56
  // A better separator should be a comma (,). This constant gives you the
57
  // abilty to change that.
58
  // However notice that changing this value, may have impact on existing
59
  // scripts, using space separated filenames.
60
  // Recommanded values for compatibility with older versions :
61
  //define( 'PCLZIP_SEPARATOR', ' ' );
62
  // Recommanded values for smart separation of filenames.
63
  if (!defined('PCLZIP_SEPARATOR')) {
64
    define( 'PCLZIP_SEPARATOR', '|' );
65
  }
66
67
  // ----- Error configuration
68
  // 0 : PclZip Class integrated error handling
69
  // 1 : PclError external library error handling. By enabling this
70
  //     you must ensure that you have included PclError library.
71
  // [2,...] : reserved for futur use
72
  if (!defined('PCLZIP_ERROR_EXTERNAL')) {
73
    define( 'PCLZIP_ERROR_EXTERNAL', 0 );
74
  }
75
76
  // ----- Optional static temporary directory
77
  //       By default temporary files are generated in the script current
78
  //       path.
79
  //       If defined :
80
  //       - MUST BE terminated by a '/'.
81
  //       - MUST be a valid, already created directory
82
  //       Samples :
83
  // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
84
  // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
85
  if (!defined('PCLZIP_TEMPORARY_DIR')) {
86
    define( 'PCLZIP_TEMPORARY_DIR', '' );
87
  }
88
89
  // ----- Optional threshold ratio for use of temporary files
90
  //       Pclzip sense the size of the file to add/extract and decide to
91
  //       use or not temporary file. The algorythm is looking for
92
  //       memory_limit of PHP and apply a ratio.
93
  //       threshold = memory_limit * ratio.
94
  //       Recommended values are under 0.5. Default 0.47.
95
  //       Samples :
96
  // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
97
  if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
98
    define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
99
  }
100
101
// --------------------------------------------------------------------------------
102
// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
103
// --------------------------------------------------------------------------------
104
105
  // ----- Global variables
106
  $g_pclzip_version = "2.8.2";
107
108
  // ----- Error codes
109
  //   -1 : Unable to open file in binary write mode
110
  //   -2 : Unable to open file in binary read mode
111
  //   -3 : Invalid parameters
112
  //   -4 : File does not exist
113
  //   -5 : Filename is too long (max. 255)
114
  //   -6 : Not a valid zip file
115
  //   -7 : Invalid extracted file size
116
  //   -8 : Unable to create directory
117
  //   -9 : Invalid archive extension
118
  //  -10 : Invalid archive format
119
  //  -11 : Unable to delete file (unlink)
120
  //  -12 : Unable to rename file (rename)
121
  //  -13 : Invalid header checksum
122
  //  -14 : Invalid archive size
123
  define( 'PCLZIP_ERR_USER_ABORTED', 2 );
124
  define( 'PCLZIP_ERR_NO_ERROR', 0 );
125
  define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
126
  define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
127
  define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
128
  define( 'PCLZIP_ERR_MISSING_FILE', -4 );
129
  define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
130
  define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
131
  define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
132
  define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
133
  define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
134
  define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
135
  define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
136
  define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
137
  define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
138
  define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
139
  define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
140
  define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
141
  define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
142
  define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
143
  define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
144
  define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
145
  define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
146
147
  // ----- Options values
148
  define( 'PCLZIP_OPT_PATH', 77001 );
149
  define( 'PCLZIP_OPT_ADD_PATH', 77002 );
150
  define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
151
  define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
152
  define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
153
  define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
154
  define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
155
  define( 'PCLZIP_OPT_BY_NAME', 77008 );
156
  define( 'PCLZIP_OPT_BY_INDEX', 77009 );
157
  define( 'PCLZIP_OPT_BY_EREG', 77010 );
158
  define( 'PCLZIP_OPT_BY_PREG', 77011 );
159
  define( 'PCLZIP_OPT_COMMENT', 77012 );
160
  define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
161
  define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
162
  define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
163
  define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
164
  define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
165
  // Having big trouble with crypt. Need to multiply 2 long int
166
  // which is not correctly supported by PHP ...
167
  //define( 'PCLZIP_OPT_CRYPT', 77018 );
168
  define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
169
  define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
170
  define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
171
  define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
172
  define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
173
  define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
174
  define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
175
176
  // ----- File description attributes
177
  define( 'PCLZIP_ATT_FILE_NAME', 79001 );
178
  define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
179
  define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
180
  define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
181
  define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
182
  define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
183
184
  // ----- Call backs values
185
  define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
186
  define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
187
  define( 'PCLZIP_CB_PRE_ADD', 78003 );
188
  define( 'PCLZIP_CB_POST_ADD', 78004 );
189
  /* For futur use
190
  define( 'PCLZIP_CB_PRE_LIST', 78005 );
191
  define( 'PCLZIP_CB_POST_LIST', 78006 );
192
  define( 'PCLZIP_CB_PRE_DELETE', 78007 );
193
  define( 'PCLZIP_CB_POST_DELETE', 78008 );
194
  */
195
196
/**
197
 * Class : PclZip
198
 * Description :
199
 *   PclZip is the class that represent a Zip archive.
200
 *   The public methods allow the manipulation of the archive.
201
 * Attributes :
202
 *   Attributes must not be accessed directly.
203
 * Methods :
204
 *   PclZip() : Object creator
205
 *   create() : Creates the Zip archive
206
 *   listContent() : List the content of the Zip archive
207
 *   extract() : Extract the content of the archive
208
 *   properties() : List the properties of the archive
209
 * @package chamilo.include.pclzip
210
 */
211
class PclZip {
212
    // ----- Filename of the zip file
213
    var $zipname = '';
214
215
    // ----- File descriptor of the zip file
216
    var $zip_fd = 0;
217
218
    // ----- Internal error handling
219
    var $error_code = 1;
220
    var $error_string = '';
221
222
    // ----- Current status of the magic_quotes_runtime
223
    // This value store the php configuration for magic_quotes
224
    // The class can then disable the magic_quotes and reset it after
225
    var $magic_quotes_status;
226
227
  // --------------------------------------------------------------------------------
228
  // Function : PclZip()
229
  // Description :
230
  //   Creates a PclZip object and set the name of the associated Zip archive
231
  //   filename.
232
  //   Note that no real action is taken, if the archive does not exist it is not
233
  //   created. Use create() for that.
234
  // --------------------------------------------------------------------------------
235
  function __construct($p_zipname)
236
  {
237
238
    // ----- Tests the zlib
239
    if (!function_exists('gzopen'))
240
    {
241
      die('Abort '.basename(__FILE__).' : Missing zlib extensions');
242
    }
243
244
    // ----- Set the attributes
245
    $this->zipname = $p_zipname;
246
    $this->zip_fd = 0;
247
    $this->magic_quotes_status = -1;
248
249
    // ----- Return
250
    return;
251
  }
252
  // --------------------------------------------------------------------------------
253
254
  // --------------------------------------------------------------------------------
255
  // Function :
256
  //   create($p_filelist, $p_add_dir="", $p_remove_dir="")
257
  //   create($p_filelist, $p_option, $p_option_value, ...)
258
  // Description :
259
  //   This method supports two different synopsis. The first one is historical.
260
  //   This method creates a Zip Archive. The Zip file is created in the
261
  //   filesystem. The files and directories indicated in $p_filelist
262
  //   are added in the archive. See the parameters description for the
263
  //   supported format of $p_filelist.
264
  //   When a directory is in the list, the directory and its content is added
265
  //   in the archive.
266
  //   In this synopsis, the function takes an optional variable list of
267
  //   options. See bellow the supported options.
268
  // Parameters :
269
  //   $p_filelist : An array containing file or directory names, or
270
  //                 a string containing one filename or one directory name, or
271
  //                 a string containing a list of filenames and/or directory
272
  //                 names separated by spaces.
273
  //   $p_add_dir : A path to add before the real path of the archived file,
274
  //                in order to have it memorized in the archive.
275
  //   $p_remove_dir : A path to remove from the real path of the file to archive,
276
  //                   in order to have a shorter path memorized in the archive.
277
  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
278
  //                   is removed first, before $p_add_dir is added.
279
  // Options :
280
  //   PCLZIP_OPT_ADD_PATH :
281
  //   PCLZIP_OPT_REMOVE_PATH :
282
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
283
  //   PCLZIP_OPT_COMMENT :
284
  //   PCLZIP_CB_PRE_ADD :
285
  //   PCLZIP_CB_POST_ADD :
286
  // Return Values :
287
  //   0 on failure,
288
  //   The list of the added files, with a status of the add action.
289
  //   (see PclZip::listContent() for list entry format)
290
  // --------------------------------------------------------------------------------
291
  function create($p_filelist)
292
  {
293
    $v_result=1;
294
295
    // ----- Reset the error handler
296
    $this->privErrorReset();
297
298
    // ----- Set default values
299
    $v_options = array();
300
    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
301
302
    // ----- Look for variable options arguments
303
    $v_size = func_num_args();
304
305
    // ----- Look for arguments
306
    if ($v_size > 1) {
307
      // ----- Get the arguments
308
      $v_arg_list = func_get_args();
309
310
      // ----- Remove from the options list the first argument
311
      array_shift($v_arg_list);
312
      $v_size--;
313
314
      // ----- Look for first arg
315
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
316
317
        // ----- Parse the options
318
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
319
                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
320
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
321
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
322
                                                   PCLZIP_CB_PRE_ADD => 'optional',
323
                                                   PCLZIP_CB_POST_ADD => 'optional',
324
                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
325
                                                   PCLZIP_OPT_COMMENT => 'optional',
326
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
327
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
328
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
329
                                                   //, PCLZIP_OPT_CRYPT => 'optional'
330
                                             ));
331
        if ($v_result != 1) {
332
          return 0;
333
        }
334
      }
335
336
      // ----- Look for 2 args
337
      // Here we need to support the first historic synopsis of the
338
      // method.
339 View Code Duplication
      else {
340
341
        // ----- Get the first argument
342
        $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
343
344
        // ----- Look for the optional second argument
345
        if ($v_size == 2) {
346
          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
347
        }
348
        else if ($v_size > 2) {
349
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
350
		                       "Invalid number / type of arguments");
351
          return 0;
352
        }
353
      }
354
    }
355
356
    // ----- Look for default option values
357
    $this->privOptionDefaultThreshold($v_options);
358
359
    // ----- Init
360
    $v_string_list = array();
361
    $v_att_list = array();
362
    $v_filedescr_list = array();
363
    $p_result_list = array();
364
365
    // ----- Look if the $p_filelist is really an array
366 View Code Duplication
    if (is_array($p_filelist)) {
367
368
      // ----- Look if the first element is also an array
369
      //       This will mean that this is a file description entry
370
      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
371
        $v_att_list = $p_filelist;
372
      }
373
374
      // ----- The list is a list of string names
375
      else {
376
        $v_string_list = $p_filelist;
377
      }
378
    }
379
380
    // ----- Look if the $p_filelist is a string
381
    else if (is_string($p_filelist)) {
382
      // ----- Create a list from the string
383
      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
384
    }
385
386
    // ----- Invalid variable type for $p_filelist
387
    else {
388
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
389
      return 0;
390
    }
391
392
    // ----- Reformat the string list
393 View Code Duplication
    if (sizeof($v_string_list) != 0) {
394
      foreach ($v_string_list as $v_string) {
395
        if ($v_string != '') {
396
          $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
397
        }
398
        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...
399
        }
400
      }
401
    }
402
403
    // ----- For each file in the list check the attributes
404
    $v_supported_attributes
405
    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
406
             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
407
             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
408
             ,PCLZIP_ATT_FILE_MTIME => 'optional'
409
             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
410
             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
411
						);
412 View Code Duplication
    foreach ($v_att_list as $v_entry) {
413
      $v_result = $this->privFileDescrParseAtt($v_entry,
414
                                               $v_filedescr_list[],
415
                                               $v_options,
416
                                               $v_supported_attributes);
417
      if ($v_result != 1) {
418
        return 0;
419
      }
420
    }
421
422
    // ----- Expand the filelist (expand directories)
423
    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
424
    if ($v_result != 1) {
425
      return 0;
426
    }
427
428
    // ----- Call the create fct
429
    $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
430
    if ($v_result != 1) {
431
      return 0;
432
    }
433
434
    // ----- Return
435
    return $p_result_list;
436
  }
437
  // --------------------------------------------------------------------------------
438
439
  // --------------------------------------------------------------------------------
440
  // Function :
441
  //   add($p_filelist, $p_add_dir="", $p_remove_dir="")
442
  //   add($p_filelist, $p_option, $p_option_value, ...)
443
  // Description :
444
  //   This method supports two synopsis. The first one is historical.
445
  //   This methods add the list of files in an existing archive.
446
  //   If a file with the same name already exists, it is added at the end of the
447
  //   archive, the first one is still present.
448
  //   If the archive does not exist, it is created.
449
  // Parameters :
450
  //   $p_filelist : An array containing file or directory names, or
451
  //                 a string containing one filename or one directory name, or
452
  //                 a string containing a list of filenames and/or directory
453
  //                 names separated by spaces.
454
  //   $p_add_dir : A path to add before the real path of the archived file,
455
  //                in order to have it memorized in the archive.
456
  //   $p_remove_dir : A path to remove from the real path of the file to archive,
457
  //                   in order to have a shorter path memorized in the archive.
458
  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
459
  //                   is removed first, before $p_add_dir is added.
460
  // Options :
461
  //   PCLZIP_OPT_ADD_PATH :
462
  //   PCLZIP_OPT_REMOVE_PATH :
463
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
464
  //   PCLZIP_OPT_COMMENT :
465
  //   PCLZIP_OPT_ADD_COMMENT :
466
  //   PCLZIP_OPT_PREPEND_COMMENT :
467
  //   PCLZIP_CB_PRE_ADD :
468
  //   PCLZIP_CB_POST_ADD :
469
  // Return Values :
470
  //   0 on failure,
471
  //   The list of the added files, with a status of the add action.
472
  //   (see PclZip::listContent() for list entry format)
473
  // --------------------------------------------------------------------------------
474
  function add($p_filelist)
475
  {
476
    $v_result=1;
477
478
    // ----- Reset the error handler
479
    $this->privErrorReset();
480
481
    // ----- Set default values
482
    $v_options = array();
483
    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
484
485
    // ----- Look for variable options arguments
486
    $v_size = func_num_args();
487
488
    // ----- Look for arguments
489
    if ($v_size > 1) {
490
      // ----- Get the arguments
491
      $v_arg_list = func_get_args();
492
493
      // ----- Remove form the options list the first argument
494
      array_shift($v_arg_list);
495
      $v_size--;
496
497
      // ----- Look for first arg
498
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
499
500
        // ----- Parse the options
501
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
502
                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
503
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
504
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
505
                                                   PCLZIP_CB_PRE_ADD => 'optional',
506
                                                   PCLZIP_CB_POST_ADD => 'optional',
507
                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
508
                                                   PCLZIP_OPT_COMMENT => 'optional',
509
                                                   PCLZIP_OPT_ADD_COMMENT => 'optional',
510
                                                   PCLZIP_OPT_PREPEND_COMMENT => 'optional',
511
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
512
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
513
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
514
                                                   //, PCLZIP_OPT_CRYPT => 'optional'
515
												   ));
516
        if ($v_result != 1) {
517
          return 0;
518
        }
519
      }
520
521
      // ----- Look for 2 args
522
      // Here we need to support the first historic synopsis of the
523
      // method.
524 View Code Duplication
      else {
525
526
        // ----- Get the first argument
527
        $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
528
529
        // ----- Look for the optional second argument
530
        if ($v_size == 2) {
531
          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
532
        }
533
        else if ($v_size > 2) {
534
          // ----- Error log
535
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
536
537
          // ----- Return
538
          return 0;
539
        }
540
      }
541
    }
542
543
    // ----- Look for default option values
544
    $this->privOptionDefaultThreshold($v_options);
545
546
    // ----- Init
547
    $v_string_list = array();
548
    $v_att_list = array();
549
    $v_filedescr_list = array();
550
    $p_result_list = array();
551
552
    // ----- Look if the $p_filelist is really an array
553 View Code Duplication
    if (is_array($p_filelist)) {
554
555
      // ----- Look if the first element is also an array
556
      //       This will mean that this is a file description entry
557
      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
558
        $v_att_list = $p_filelist;
559
      }
560
561
      // ----- The list is a list of string names
562
      else {
563
        $v_string_list = $p_filelist;
564
      }
565
    }
566
567
    // ----- Look if the $p_filelist is a string
568
    else if (is_string($p_filelist)) {
569
      // ----- Create a list from the string
570
      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
571
    }
572
573
    // ----- Invalid variable type for $p_filelist
574
    else {
575
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
576
      return 0;
577
    }
578
579
    // ----- Reformat the string list
580 View Code Duplication
    if (sizeof($v_string_list) != 0) {
581
      foreach ($v_string_list as $v_string) {
582
        $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
583
      }
584
    }
585
586
    // ----- For each file in the list check the attributes
587
    $v_supported_attributes
588
    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
589
             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
590
             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
591
             ,PCLZIP_ATT_FILE_MTIME => 'optional'
592
             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
593
             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
594
						);
595 View Code Duplication
    foreach ($v_att_list as $v_entry) {
596
      $v_result = $this->privFileDescrParseAtt($v_entry,
597
                                               $v_filedescr_list[],
598
                                               $v_options,
599
                                               $v_supported_attributes);
600
      if ($v_result != 1) {
601
        return 0;
602
      }
603
    }
604
605
    // ----- Expand the filelist (expand directories)
606
    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
607
    if ($v_result != 1) {
608
      return 0;
609
    }
610
611
    // ----- Call the create fct
612
    $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
613
    if ($v_result != 1) {
614
      return 0;
615
    }
616
617
    // ----- Return
618
    return $p_result_list;
619
  }
620
  // --------------------------------------------------------------------------------
621
622
  // --------------------------------------------------------------------------------
623
  // Function : listContent()
624
  // Description :
625
  //   This public method, gives the list of the files and directories, with their
626
  //   properties.
627
  //   The properties of each entries in the list are (used also in other functions) :
628
  //     filename : Name of the file. For a create or add action it is the filename
629
  //                given by the user. For an extract function it is the filename
630
  //                of the extracted file.
631
  //     stored_filename : Name of the file / directory stored in the archive.
632
  //     size : Size of the stored file.
633
  //     compressed_size : Size of the file's data compressed in the archive
634
  //                       (without the headers overhead)
635
  //     mtime : Last known modification date of the file (UNIX timestamp)
636
  //     comment : Comment associated with the file
637
  //     folder : true | false
638
  //     index : index of the file in the archive
639
  //     status : status of the action (depending of the action) :
640
  //              Values are :
641
  //                ok : OK !
642
  //                filtered : the file / dir is not extracted (filtered by user)
643
  //                already_a_directory : the file can not be extracted because a
644
  //                                      directory with the same name already exists
645
  //                write_protected : the file can not be extracted because a file
646
  //                                  with the same name already exists and is
647
  //                                  write protected
648
  //                newer_exist : the file was not extracted because a newer file exists
649
  //                path_creation_fail : the file is not extracted because the folder
650
  //                                     does not exist and can not be created
651
  //                write_error : the file was not extracted because there was a
652
  //                              error while writing the file
653
  //                read_error : the file was not extracted because there was a error
654
  //                             while reading the file
655
  //                invalid_header : the file was not extracted because of an archive
656
  //                                 format error (bad file header)
657
  //   Note that each time a method can continue operating when there
658
  //   is an action error on a file, the error is only logged in the file status.
659
  // Return Values :
660
  //   0 on an unrecoverable failure,
661
  //   The list of the files in the archive.
662
  // --------------------------------------------------------------------------------
663
  function listContent()
664
  {
665
    $v_result=1;
666
667
    // ----- Reset the error handler
668
    $this->privErrorReset();
669
670
    // ----- Check archive
671
    if (!$this->privCheckFormat()) {
672
      return(0);
673
    }
674
675
    // ----- Call the extracting fct
676
    $p_list = array();
677
    if (($v_result = $this->privList($p_list)) != 1)
678
    {
679
      unset($p_list);
680
      return(0);
681
    }
682
683
    // ----- Return
684
    return $p_list;
685
  }
686
  // --------------------------------------------------------------------------------
687
688
  // --------------------------------------------------------------------------------
689
  // Function :
690
  //   extract($p_path="./", $p_remove_path="")
691
  //   extract([$p_option, $p_option_value, ...])
692
  // Description :
693
  //   This method supports two synopsis. The first one is historical.
694
  //   This method extract all the files / directories from the archive to the
695
  //   folder indicated in $p_path.
696
  //   If you want to ignore the 'root' part of path of the memorized files
697
  //   you can indicate this in the optional $p_remove_path parameter.
698
  //   By default, if a newer file with the same name already exists, the
699
  //   file is not extracted.
700
  //
701
  //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
702
  //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
703
  //   at the end of the path value of PCLZIP_OPT_PATH.
704
  // Parameters :
705
  //   $p_path : Path where the files and directories are to be extracted
706
  //   $p_remove_path : First part ('root' part) of the memorized path
707
  //                    (if any similar) to remove while extracting.
708
  // Options :
709
  //   PCLZIP_OPT_PATH :
710
  //   PCLZIP_OPT_ADD_PATH :
711
  //   PCLZIP_OPT_REMOVE_PATH :
712
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
713
  //   PCLZIP_CB_PRE_EXTRACT :
714
  //   PCLZIP_CB_POST_EXTRACT :
715
  // Return Values :
716
  //   0 or a negative value on failure,
717
  //   The list of the extracted files, with a status of the action.
718
  //   (see PclZip::listContent() for list entry format)
719
  // --------------------------------------------------------------------------------
720
  function extract()
721
  {
722
    $v_result=1;
723
724
    // ----- Reset the error handler
725
    $this->privErrorReset();
726
727
    // ----- Check archive
728
    if (!$this->privCheckFormat()) {
729
      return(0);
730
    }
731
732
    // ----- Set default values
733
    $v_options = array();
734
//    $v_path = "./";
735
    $v_path = '';
736
    $v_remove_path = "";
737
    $v_remove_all_path = false;
738
739
    // ----- Look for variable options arguments
740
    $v_size = func_num_args();
741
742
    // ----- Default values for option
743
    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
744
745
    // ----- Look for arguments
746
    if ($v_size > 0) {
747
      // ----- Get the arguments
748
      $v_arg_list = func_get_args();
749
750
      // ----- Look for first arg
751
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
752
753
        // ----- Parse the options
754
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
755
                                            array (PCLZIP_OPT_PATH => 'optional',
756
                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
757
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
758
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
759
                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
760
                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
761
                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
762
                                                   PCLZIP_OPT_BY_NAME => 'optional',
763
                                                   PCLZIP_OPT_BY_EREG => 'optional',
764
                                                   PCLZIP_OPT_BY_PREG => 'optional',
765
                                                   PCLZIP_OPT_BY_INDEX => 'optional',
766
                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
767
                                                   PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
768
                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
769
                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
770
                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
771
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
772
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
773
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
774
												    ));
775
        if ($v_result != 1) {
776
          return 0;
777
        }
778
779
        // ----- Set the arguments
780
        if (isset($v_options[PCLZIP_OPT_PATH])) {
781
          $v_path = $v_options[PCLZIP_OPT_PATH];
782
        }
783
        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
784
          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
785
        }
786
        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
787
          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
788
        }
789 View Code Duplication
        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
790
          // ----- Check for '/' in last path char
791
          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
792
            $v_path .= '/';
793
          }
794
          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
795
        }
796
      }
797
798
      // ----- Look for 2 args
799
      // Here we need to support the first historic synopsis of the
800
      // method.
801
      else {
802
803
        // ----- Get the first argument
804
        $v_path = $v_arg_list[0];
805
806
        // ----- Look for the optional second argument
807
        if ($v_size == 2) {
808
          $v_remove_path = $v_arg_list[1];
809
        }
810
        else if ($v_size > 2) {
811
          // ----- Error log
812
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
813
814
          // ----- Return
815
          return 0;
816
        }
817
      }
818
    }
819
820
    // ----- Look for default option values
821
    $this->privOptionDefaultThreshold($v_options);
822
823
    // ----- Trace
824
825
    // ----- Call the extracting fct
826
    $p_list = array();
827
    $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
828
	                                     $v_remove_all_path, $v_options);
829
    if ($v_result < 1) {
830
      unset($p_list);
831
      return(0);
832
    }
833
834
    // ----- Return
835
    return $p_list;
836
  }
837
  // --------------------------------------------------------------------------------
838
839
840
  // --------------------------------------------------------------------------------
841
  // Function :
842
  //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
843
  //   extractByIndex($p_index, [$p_option, $p_option_value, ...])
844
  // Description :
845
  //   This method supports two synopsis. The first one is historical.
846
  //   This method is doing a partial extract of the archive.
847
  //   The extracted files or folders are identified by their index in the
848
  //   archive (from 0 to n).
849
  //   Note that if the index identify a folder, only the folder entry is
850
  //   extracted, not all the files included in the archive.
851
  // Parameters :
852
  //   $p_index : A single index (integer) or a string of indexes of files to
853
  //              extract. The form of the string is "0,4-6,8-12" with only numbers
854
  //              and '-' for range or ',' to separate ranges. No spaces or ';'
855
  //              are allowed.
856
  //   $p_path : Path where the files and directories are to be extracted
857
  //   $p_remove_path : First part ('root' part) of the memorized path
858
  //                    (if any similar) to remove while extracting.
859
  // Options :
860
  //   PCLZIP_OPT_PATH :
861
  //   PCLZIP_OPT_ADD_PATH :
862
  //   PCLZIP_OPT_REMOVE_PATH :
863
  //   PCLZIP_OPT_REMOVE_ALL_PATH :
864
  //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
865
  //     not as files.
866
  //     The resulting content is in a new field 'content' in the file
867
  //     structure.
868
  //     This option must be used alone (any other options are ignored).
869
  //   PCLZIP_CB_PRE_EXTRACT :
870
  //   PCLZIP_CB_POST_EXTRACT :
871
  // Return Values :
872
  //   0 on failure,
873
  //   The list of the extracted files, with a status of the action.
874
  //   (see PclZip::listContent() for list entry format)
875
  // --------------------------------------------------------------------------------
876
  //function extractByIndex($p_index, options...)
877
  function extractByIndex($p_index)
878
  {
879
    $v_result=1;
880
881
    // ----- Reset the error handler
882
    $this->privErrorReset();
883
884
    // ----- Check archive
885
    if (!$this->privCheckFormat()) {
886
      return(0);
887
    }
888
889
    // ----- Set default values
890
    $v_options = array();
891
//    $v_path = "./";
892
    $v_path = '';
893
    $v_remove_path = "";
894
    $v_remove_all_path = false;
895
896
    // ----- Look for variable options arguments
897
    $v_size = func_num_args();
898
899
    // ----- Default values for option
900
    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
901
902
    // ----- Look for arguments
903
    if ($v_size > 1) {
904
      // ----- Get the arguments
905
      $v_arg_list = func_get_args();
906
907
      // ----- Remove form the options list the first argument
908
      array_shift($v_arg_list);
909
      $v_size--;
910
911
      // ----- Look for first arg
912
      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
913
914
        // ----- Parse the options
915
        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
916
                                            array (PCLZIP_OPT_PATH => 'optional',
917
                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
918
                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
919
                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
920
                                                   PCLZIP_OPT_ADD_PATH => 'optional',
921
                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
922
                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
923
                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
924
                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
925
                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
926
                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
927
                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
928
                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
929
                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
930
												   ));
931
        if ($v_result != 1) {
932
          return 0;
933
        }
934
935
        // ----- Set the arguments
936
        if (isset($v_options[PCLZIP_OPT_PATH])) {
937
          $v_path = $v_options[PCLZIP_OPT_PATH];
938
        }
939
        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
940
          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
941
        }
942
        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
943
          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
944
        }
945 View Code Duplication
        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
946
          // ----- Check for '/' in last path char
947
          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
948
            $v_path .= '/';
949
          }
950
          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
951
        }
952
        if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
953
          $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
954
        }
955
        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...
956
        }
957
      }
958
959
      // ----- Look for 2 args
960
      // Here we need to support the first historic synopsis of the
961
      // method.
962
      else {
963
964
        // ----- Get the first argument
965
        $v_path = $v_arg_list[0];
966
967
        // ----- Look for the optional second argument
968
        if ($v_size == 2) {
969
          $v_remove_path = $v_arg_list[1];
970
        }
971
        else if ($v_size > 2) {
972
          // ----- Error log
973
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
974
975
          // ----- Return
976
          return 0;
977
        }
978
      }
979
    }
980
981
    // ----- Trace
982
983
    // ----- Trick
984
    // Here I want to reuse extractByRule(), so I need to parse the $p_index
985
    // with privParseOptions()
986
    $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
987
    $v_options_trick = array();
988
    $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
989
                                        array (PCLZIP_OPT_BY_INDEX => 'optional' ));
990
    if ($v_result != 1) {
991
        return 0;
992
    }
993
    $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
994
995
    // ----- Look for default option values
996
    $this->privOptionDefaultThreshold($v_options);
997
998
    // ----- Call the extracting fct
999
    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
1000
        return(0);
1001
    }
1002
1003
    // ----- Return
1004
    return $p_list;
1005
  }
1006
  // --------------------------------------------------------------------------------
1007
1008
  // --------------------------------------------------------------------------------
1009
  // Function :
1010
  //   delete([$p_option, $p_option_value, ...])
1011
  // Description :
1012
  //   This method removes files from the archive.
1013
  //   If no parameters are given, then all the archive is emptied.
1014
  // Parameters :
1015
  //   None or optional arguments.
1016
  // Options :
1017
  //   PCLZIP_OPT_BY_INDEX :
1018
  //   PCLZIP_OPT_BY_NAME :
1019
  //   PCLZIP_OPT_BY_EREG :
1020
  //   PCLZIP_OPT_BY_PREG :
1021
  // Return Values :
1022
  //   0 on failure,
1023
  //   The list of the files which are still present in the archive.
1024
  //   (see PclZip::listContent() for list entry format)
1025
  // --------------------------------------------------------------------------------
1026
  function delete()
1027
  {
1028
    $v_result=1;
1029
1030
    // ----- Reset the error handler
1031
    $this->privErrorReset();
1032
1033
    // ----- Check archive
1034
    if (!$this->privCheckFormat()) {
1035
      return(0);
1036
    }
1037
1038
    // ----- Set default values
1039
    $v_options = array();
1040
1041
    // ----- Look for variable options arguments
1042
    $v_size = func_num_args();
1043
1044
    // ----- Look for arguments
1045
    if ($v_size > 0) {
1046
      // ----- Get the arguments
1047
      $v_arg_list = func_get_args();
1048
1049
      // ----- Parse the options
1050
      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1051
                                        array (PCLZIP_OPT_BY_NAME => 'optional',
1052
                                               PCLZIP_OPT_BY_EREG => 'optional',
1053
                                               PCLZIP_OPT_BY_PREG => 'optional',
1054
                                               PCLZIP_OPT_BY_INDEX => 'optional' ));
1055
      if ($v_result != 1) {
1056
          return 0;
1057
      }
1058
    }
1059
1060
    // ----- Magic quotes trick
1061
    $this->privDisableMagicQuotes();
1062
1063
    // ----- Call the delete fct
1064
    $v_list = array();
1065
    if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1066
      $this->privSwapBackMagicQuotes();
1067
      unset($v_list);
1068
      return(0);
1069
    }
1070
1071
    // ----- Magic quotes trick
1072
    $this->privSwapBackMagicQuotes();
1073
1074
    // ----- Return
1075
    return $v_list;
1076
  }
1077
  // --------------------------------------------------------------------------------
1078
1079
  // --------------------------------------------------------------------------------
1080
  // Function : deleteByIndex()
1081
  // Description :
1082
  //   ***** Deprecated *****
1083
  //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1084
  // --------------------------------------------------------------------------------
1085
  function deleteByIndex($p_index)
1086
  {
1087
1088
    $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1089
1090
    // ----- Return
1091
    return $p_list;
1092
  }
1093
  // --------------------------------------------------------------------------------
1094
1095
  // --------------------------------------------------------------------------------
1096
  // Function : properties()
1097
  // Description :
1098
  //   This method gives the properties of the archive.
1099
  //   The properties are :
1100
  //     nb : Number of files in the archive
1101
  //     comment : Comment associated with the archive file
1102
  //     status : not_exist, ok
1103
  // Parameters :
1104
  //   None
1105
  // Return Values :
1106
  //   0 on failure,
1107
  //   An array with the archive properties.
1108
  // --------------------------------------------------------------------------------
1109
  function properties()
1110
  {
1111
1112
    // ----- Reset the error handler
1113
    $this->privErrorReset();
1114
1115
    // ----- Magic quotes trick
1116
    $this->privDisableMagicQuotes();
1117
1118
    // ----- Check archive
1119
    if (!$this->privCheckFormat()) {
1120
      $this->privSwapBackMagicQuotes();
1121
      return(0);
1122
    }
1123
1124
    // ----- Default properties
1125
    $v_prop = array();
1126
    $v_prop['comment'] = '';
1127
    $v_prop['nb'] = 0;
1128
    $v_prop['status'] = 'not_exist';
1129
1130
    // ----- Look if file exists
1131
    if (@is_file($this->zipname))
1132
    {
1133
      // ----- Open the zip file
1134 View Code Duplication
      if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1135
      {
1136
        $this->privSwapBackMagicQuotes();
1137
1138
        // ----- Error log
1139
        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1140
1141
        // ----- Return
1142
        return 0;
1143
      }
1144
1145
      // ----- Read the central directory informations
1146
      $v_central_dir = array();
1147
      if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1148
      {
1149
        $this->privSwapBackMagicQuotes();
1150
        return 0;
1151
      }
1152
1153
      // ----- Close the zip file
1154
      $this->privCloseFd();
1155
1156
      // ----- Set the user attributes
1157
      $v_prop['comment'] = $v_central_dir['comment'];
1158
      $v_prop['nb'] = $v_central_dir['entries'];
1159
      $v_prop['status'] = 'ok';
1160
    }
1161
1162
    // ----- Magic quotes trick
1163
    $this->privSwapBackMagicQuotes();
1164
1165
    // ----- Return
1166
    return $v_prop;
1167
  }
1168
  // --------------------------------------------------------------------------------
1169
1170
  // --------------------------------------------------------------------------------
1171
  // Function : duplicate()
1172
  // Description :
1173
  //   This method creates an archive by copying the content of an other one. If
1174
  //   the archive already exist, it is replaced by the new one without any warning.
1175
  // Parameters :
1176
  //   $p_archive : The filename of a valid archive, or
1177
  //                a valid PclZip object.
1178
  // Return Values :
1179
  //   1 on success.
1180
  //   0 or a negative value on error (error code).
1181
  // --------------------------------------------------------------------------------
1182
  function duplicate($p_archive)
1183
  {
1184
    $v_result = 1;
1185
1186
    // ----- Reset the error handler
1187
    $this->privErrorReset();
1188
1189
    // ----- Look if the $p_archive is a PclZip object
1190
    if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1191
    {
1192
1193
      // ----- Duplicate the archive
1194
      $v_result = $this->privDuplicate($p_archive->zipname);
1195
    }
1196
1197
    // ----- Look if the $p_archive is a string (so a filename)
1198
    else if (is_string($p_archive))
1199
    {
1200
1201
      // ----- Check that $p_archive is a valid zip file
1202
      // TBC : Should also check the archive format
1203
      if (!is_file($p_archive)) {
1204
        // ----- Error log
1205
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1206
        $v_result = PCLZIP_ERR_MISSING_FILE;
1207
      }
1208
      else {
1209
        // ----- Duplicate the archive
1210
        $v_result = $this->privDuplicate($p_archive);
1211
      }
1212
    }
1213
1214
    // ----- Invalid variable
1215
    else
1216
    {
1217
      // ----- Error log
1218
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1219
      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1220
    }
1221
1222
    // ----- Return
1223
    return $v_result;
1224
  }
1225
  // --------------------------------------------------------------------------------
1226
1227
  // --------------------------------------------------------------------------------
1228
  // Function : merge()
1229
  // Description :
1230
  //   This method merge the $p_archive_to_add archive at the end of the current
1231
  //   one ($this).
1232
  //   If the archive ($this) does not exist, the merge becomes a duplicate.
1233
  //   If the $p_archive_to_add archive does not exist, the merge is a success.
1234
  // Parameters :
1235
  //   $p_archive_to_add : It can be directly the filename of a valid zip archive,
1236
  //                       or a PclZip object archive.
1237
  // Return Values :
1238
  //   1 on success,
1239
  //   0 or negative values on error (see below).
1240
  // --------------------------------------------------------------------------------
1241
  function merge($p_archive_to_add)
1242
  {
1243
    $v_result = 1;
1244
1245
    // ----- Reset the error handler
1246
    $this->privErrorReset();
1247
1248
    // ----- Check archive
1249
    if (!$this->privCheckFormat()) {
1250
      return(0);
1251
    }
1252
1253
    // ----- Look if the $p_archive_to_add is a PclZip object
1254
    if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1255
    {
1256
1257
      // ----- Merge the archive
1258
      $v_result = $this->privMerge($p_archive_to_add);
1259
    }
1260
1261
    // ----- Look if the $p_archive_to_add is a string (so a filename)
1262
    else if (is_string($p_archive_to_add))
1263
    {
1264
1265
      // ----- Create a temporary archive
1266
      $v_object_archive = new PclZip($p_archive_to_add);
1267
1268
      // ----- Merge the archive
1269
      $v_result = $this->privMerge($v_object_archive);
1270
    }
1271
1272
    // ----- Invalid variable
1273
    else
1274
    {
1275
      // ----- Error log
1276
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1277
      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1278
    }
1279
1280
    // ----- Return
1281
    return $v_result;
1282
  }
1283
  // --------------------------------------------------------------------------------
1284
1285
1286
1287
  // --------------------------------------------------------------------------------
1288
  // Function : errorCode()
1289
  // Description :
1290
  // Parameters :
1291
  // --------------------------------------------------------------------------------
1292
  function errorCode()
1293
  {
1294
    if (PCLZIP_ERROR_EXTERNAL == 1) {
1295
      return(PclErrorCode());
1296
    }
1297
    else {
1298
      return($this->error_code);
1299
    }
1300
  }
1301
  // --------------------------------------------------------------------------------
1302
1303
  // --------------------------------------------------------------------------------
1304
  // Function : errorName()
1305
  // Description :
1306
  // Parameters :
1307
  // --------------------------------------------------------------------------------
1308
  function errorName($p_with_code=false)
1309
  {
1310
    $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1311
                      PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1312
                      PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1313
                      PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1314
                      PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1315
                      PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1316
                      PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1317
                      PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1318
                      PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1319
                      PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1320
                      PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1321
                      PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1322
                      PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1323
                      PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1324
                      PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1325
                      PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1326
                      PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1327
                      PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1328
                      PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1329
                      ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1330
                      ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1331
                    );
1332
1333
    if (isset($v_name[$this->error_code])) {
1334
      $v_value = $v_name[$this->error_code];
1335
    }
1336
    else {
1337
      $v_value = 'NoName';
1338
    }
1339
1340
    if ($p_with_code) {
1341
      return($v_value.' ('.$this->error_code.')');
1342
    }
1343
    else {
1344
      return($v_value);
1345
    }
1346
  }
1347
  // --------------------------------------------------------------------------------
1348
1349
  // --------------------------------------------------------------------------------
1350
  // Function : errorInfo()
1351
  // Description :
1352
  // Parameters :
1353
  // --------------------------------------------------------------------------------
1354
  function errorInfo($p_full=false)
1355
  {
1356
    if (PCLZIP_ERROR_EXTERNAL == 1) {
1357
      return(PclErrorString());
1358
    }
1359
    else {
1360
      if ($p_full) {
1361
        return($this->errorName(true)." : ".$this->error_string);
1362
      }
1363
      else {
1364
        return($this->error_string." [code ".$this->error_code."]");
1365
      }
1366
    }
1367
  }
1368
  // --------------------------------------------------------------------------------
1369
1370
1371
// --------------------------------------------------------------------------------
1372
// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1373
// *****                                                        *****
1374
// *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
1375
// --------------------------------------------------------------------------------
1376
1377
1378
1379
  // --------------------------------------------------------------------------------
1380
  // Function : privCheckFormat()
1381
  // Description :
1382
  //   This method check that the archive exists and is a valid zip archive.
1383
  //   Several level of check exists. (futur)
1384
  // Parameters :
1385
  //   $p_level : Level of check. Default 0.
1386
  //              0 : Check the first bytes (magic codes) (default value))
1387
  //              1 : 0 + Check the central directory (futur)
1388
  //              2 : 1 + Check each file header (futur)
1389
  // Return Values :
1390
  //   true on success,
1391
  //   false on error, the error code is set.
1392
  // --------------------------------------------------------------------------------
1393
  function privCheckFormat($p_level=0)
1394
  {
1395
    $v_result = true;
1396
1397
	// ----- Reset the file system cache
1398
    clearstatcache();
1399
1400
    // ----- Reset the error handler
1401
    $this->privErrorReset();
1402
1403
    // ----- Look if the file exits
1404
    if (!is_file($this->zipname)) {
1405
      // ----- Error log
1406
      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1407
      return(false);
1408
    }
1409
1410
    // ----- Check that the file is readeable
1411
    if (!is_readable($this->zipname)) {
1412
      // ----- Error log
1413
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1414
      return(false);
1415
    }
1416
1417
    // ----- Check the magic code
1418
    // TBC
1419
1420
    // ----- Check the central header
1421
    // TBC
1422
1423
    // ----- Check each file header
1424
    // TBC
1425
1426
    // ----- Return
1427
    return $v_result;
1428
  }
1429
  // --------------------------------------------------------------------------------
1430
1431
  // --------------------------------------------------------------------------------
1432
  // Function : privParseOptions()
1433
  // Description :
1434
  //   This internal methods reads the variable list of arguments ($p_options_list,
1435
  //   $p_size) and generate an array with the options and values ($v_result_list).
1436
  //   $v_requested_options contains the options that can be present and those that
1437
  //   must be present.
1438
  //   $v_requested_options is an array, with the option value as key, and 'optional',
1439
  //   or 'mandatory' as value.
1440
  // Parameters :
1441
  //   See above.
1442
  // Return Values :
1443
  //   1 on success.
1444
  //   0 on failure.
1445
  // --------------------------------------------------------------------------------
1446
  function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1447
  {
1448
    $v_result=1;
1449
1450
    // ----- Read the options
1451
    $i=0;
1452
    while ($i<$p_size) {
1453
1454
      // ----- Check if the option is supported
1455 View Code Duplication
      if (!isset($v_requested_options[$p_options_list[$i]])) {
1456
        // ----- Error log
1457
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1458
1459
        // ----- Return
1460
        return PclZip::errorCode();
1461
      }
1462
1463
      // ----- Look for next option
1464
      switch ($p_options_list[$i]) {
1465
        // ----- Look for options that request a path value
1466
        case PCLZIP_OPT_PATH :
1467
        case PCLZIP_OPT_REMOVE_PATH :
1468 View Code Duplication
        case PCLZIP_OPT_ADD_PATH :
1469
          // ----- Check the number of parameters
1470
          if (($i+1) >= $p_size) {
1471
            // ----- Error log
1472
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1473
1474
            // ----- Return
1475
            return PclZip::errorCode();
1476
          }
1477
1478
          // ----- Get the value
1479
          $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1480
          $i++;
1481
        break;
1482
1483
        case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
1484
          // ----- Check the number of parameters
1485
          if (($i+1) >= $p_size) {
1486
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1487
            return PclZip::errorCode();
1488
          }
1489
1490
          // ----- Check for incompatible options
1491
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1492
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1493
            return PclZip::errorCode();
1494
          }
1495
1496
          // ----- Check the value
1497
          $v_value = $p_options_list[$i+1];
1498
          if ((!is_integer($v_value)) || ($v_value<0)) {
1499
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1500
            return PclZip::errorCode();
1501
          }
1502
1503
          // ----- Get the value (and convert it in bytes)
1504
          $v_result_list[$p_options_list[$i]] = $v_value*1048576;
1505
          $i++;
1506
        break;
1507
1508
        case PCLZIP_OPT_TEMP_FILE_ON :
1509
          // ----- Check for incompatible options
1510
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1511
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1512
            return PclZip::errorCode();
1513
          }
1514
1515
          $v_result_list[$p_options_list[$i]] = true;
1516
        break;
1517
1518
        case PCLZIP_OPT_TEMP_FILE_OFF :
1519
          // ----- Check for incompatible options
1520
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1521
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1522
            return PclZip::errorCode();
1523
          }
1524
          // ----- Check for incompatible options
1525
          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1526
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1527
            return PclZip::errorCode();
1528
          }
1529
1530
          $v_result_list[$p_options_list[$i]] = true;
1531
        break;
1532
1533
        case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1534
          // ----- Check the number of parameters
1535
          if (($i+1) >= $p_size) {
1536
            // ----- Error log
1537
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1538
1539
            // ----- Return
1540
            return PclZip::errorCode();
1541
          }
1542
1543
          // ----- Get the value
1544
          if (   is_string($p_options_list[$i+1])
1545
              && ($p_options_list[$i+1] != '')) {
1546
            $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1547
            $i++;
1548
          }
1549
          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...
1550
          }
1551
        break;
1552
1553
        // ----- Look for options that request an array of string for value
1554
        case PCLZIP_OPT_BY_NAME :
1555
          // ----- Check the number of parameters
1556
          if (($i+1) >= $p_size) {
1557
            // ----- Error log
1558
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1559
1560
            // ----- Return
1561
            return PclZip::errorCode();
1562
          }
1563
1564
          // ----- Get the value
1565
          if (is_string($p_options_list[$i+1])) {
1566
              $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1567
          }
1568
          else if (is_array($p_options_list[$i+1])) {
1569
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1570
          }
1571
          else {
1572
            // ----- Error log
1573
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1574
1575
            // ----- Return
1576
            return PclZip::errorCode();
1577
          }
1578
          $i++;
1579
        break;
1580
1581
        // ----- Look for options that request an EREG or PREG expression
1582
        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...
1583
          // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
1584
          // to PCLZIP_OPT_BY_PREG
1585
          $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1586 View Code Duplication
        case PCLZIP_OPT_BY_PREG :
1587
        //case PCLZIP_OPT_CRYPT :
1588
          // ----- Check the number of parameters
1589
          if (($i+1) >= $p_size) {
1590
            // ----- Error log
1591
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1592
1593
            // ----- Return
1594
            return PclZip::errorCode();
1595
          }
1596
1597
          // ----- Get the value
1598
          if (is_string($p_options_list[$i+1])) {
1599
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1600
          }
1601
          else {
1602
            // ----- Error log
1603
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1604
1605
            // ----- Return
1606
            return PclZip::errorCode();
1607
          }
1608
          $i++;
1609
        break;
1610
1611
        // ----- Look for options that takes a string
1612
        case PCLZIP_OPT_COMMENT :
1613
        case PCLZIP_OPT_ADD_COMMENT :
1614 View Code Duplication
        case PCLZIP_OPT_PREPEND_COMMENT :
1615
          // ----- Check the number of parameters
1616
          if (($i+1) >= $p_size) {
1617
            // ----- Error log
1618
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1619
			                     "Missing parameter value for option '"
1620
								 .PclZipUtilOptionText($p_options_list[$i])
1621
								 ."'");
1622
1623
            // ----- Return
1624
            return PclZip::errorCode();
1625
          }
1626
1627
          // ----- Get the value
1628
          if (is_string($p_options_list[$i+1])) {
1629
              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1630
          }
1631
          else {
1632
            // ----- Error log
1633
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1634
			                     "Wrong parameter value for option '"
1635
								 .PclZipUtilOptionText($p_options_list[$i])
1636
								 ."'");
1637
1638
            // ----- Return
1639
            return PclZip::errorCode();
1640
          }
1641
          $i++;
1642
        break;
1643
1644
        // ----- Look for options that request an array of index
1645
        case PCLZIP_OPT_BY_INDEX :
1646
          // ----- Check the number of parameters
1647
          if (($i+1) >= $p_size) {
1648
            // ----- Error log
1649
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1650
1651
            // ----- Return
1652
            return PclZip::errorCode();
1653
          }
1654
1655
          // ----- Get the value
1656
          $v_work_list = array();
1657
          if (is_string($p_options_list[$i+1])) {
1658
1659
              // ----- Remove spaces
1660
              $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1661
1662
              // ----- Parse items
1663
              $v_work_list = explode(",", $p_options_list[$i+1]);
1664
          }
1665
          else if (is_integer($p_options_list[$i+1])) {
1666
              $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1667
          }
1668
          else if (is_array($p_options_list[$i+1])) {
1669
              $v_work_list = $p_options_list[$i+1];
1670
          }
1671
          else {
1672
            // ----- Error log
1673
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1674
1675
            // ----- Return
1676
            return PclZip::errorCode();
1677
          }
1678
1679
          // ----- Reduce the index list
1680
          // each index item in the list must be a couple with a start and
1681
          // an end value : [0,3], [5-5], [8-10], ...
1682
          // ----- Check the format of each item
1683
          $v_sort_flag=false;
1684
          $v_sort_value=0;
1685
          for ($j=0; $j<sizeof($v_work_list); $j++) {
1686
              // ----- Explode the item
1687
              $v_item_list = explode("-", $v_work_list[$j]);
1688
              $v_size_item_list = sizeof($v_item_list);
1689
1690
              // ----- TBC : Here we might check that each item is a
1691
              // real integer ...
1692
1693
              // ----- Look for single value
1694
              if ($v_size_item_list == 1) {
1695
                  // ----- Set the option value
1696
                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1697
                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1698
              }
1699
              elseif ($v_size_item_list == 2) {
1700
                  // ----- Set the option value
1701
                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1702
                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1703
              }
1704
              else {
1705
                  // ----- Error log
1706
                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1707
1708
                  // ----- Return
1709
                  return PclZip::errorCode();
1710
              }
1711
1712
1713
              // ----- Look for list sort
1714
              if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1715
                  $v_sort_flag=true;
1716
1717
                  // ----- TBC : An automatic sort should be writen ...
1718
                  // ----- Error log
1719
                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1720
1721
                  // ----- Return
1722
                  return PclZip::errorCode();
1723
              }
1724
              $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1725
          }
1726
1727
          // ----- Sort the items
1728
          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...
1729
              // TBC : To Be Completed
1730
          }
1731
1732
          // ----- Next option
1733
          $i++;
1734
        break;
1735
1736
        // ----- Look for options that request no value
1737
        case PCLZIP_OPT_REMOVE_ALL_PATH :
1738
        case PCLZIP_OPT_EXTRACT_AS_STRING :
1739
        case PCLZIP_OPT_NO_COMPRESSION :
1740
        case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1741
        case PCLZIP_OPT_REPLACE_NEWER :
1742
        case PCLZIP_OPT_STOP_ON_ERROR :
1743
          $v_result_list[$p_options_list[$i]] = true;
1744
        break;
1745
1746
        // ----- Look for options that request an octal value
1747 View Code Duplication
        case PCLZIP_OPT_SET_CHMOD :
1748
          // ----- Check the number of parameters
1749
          if (($i+1) >= $p_size) {
1750
            // ----- Error log
1751
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1752
1753
            // ----- Return
1754
            return PclZip::errorCode();
1755
          }
1756
1757
          // ----- Get the value
1758
          $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1759
          $i++;
1760
        break;
1761
1762
        // ----- Look for options that request a call-back
1763
        case PCLZIP_CB_PRE_EXTRACT :
1764
        case PCLZIP_CB_POST_EXTRACT :
1765
        case PCLZIP_CB_PRE_ADD :
1766
        case PCLZIP_CB_POST_ADD :
1767
        /* for futur use
1768
        case PCLZIP_CB_PRE_DELETE :
1769
        case PCLZIP_CB_POST_DELETE :
1770
        case PCLZIP_CB_PRE_LIST :
1771
        case PCLZIP_CB_POST_LIST :
1772
        */
1773
          // ----- Check the number of parameters
1774
          if (($i+1) >= $p_size) {
1775
            // ----- Error log
1776
            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1777
1778
            // ----- Return
1779
            return PclZip::errorCode();
1780
          }
1781
1782
          // ----- Get the value
1783
          $v_function_name = $p_options_list[$i+1];
1784
1785
          // ----- Check that the value is a valid existing function
1786
          if (!function_exists($v_function_name)) {
1787
            // ----- Error log
1788
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1789
1790
            // ----- Return
1791
            return PclZip::errorCode();
1792
          }
1793
1794
          // ----- Set the attribute
1795
          $v_result_list[$p_options_list[$i]] = $v_function_name;
1796
          $i++;
1797
        break;
1798
1799
        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...
1800
          // ----- Error log
1801
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1802
		                       "Unknown parameter '"
1803
							   .$p_options_list[$i]."'");
1804
1805
          // ----- Return
1806
          return PclZip::errorCode();
1807
      }
1808
1809
      // ----- Next options
1810
      $i++;
1811
    }
1812
1813
    // ----- Look for mandatory options
1814 View Code Duplication
    if ($v_requested_options !== false) {
1815
      for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1816
        // ----- Look for mandatory option
1817
        if ($v_requested_options[$key] == 'mandatory') {
1818
          // ----- Look if present
1819
          if (!isset($v_result_list[$key])) {
1820
            // ----- Error log
1821
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1822
1823
            // ----- Return
1824
            return PclZip::errorCode();
1825
          }
1826
        }
1827
      }
1828
    }
1829
1830
    // ----- Look for default values
1831
    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...
1832
1833
    }
1834
1835
    // ----- Return
1836
    return $v_result;
1837
  }
1838
  // --------------------------------------------------------------------------------
1839
1840
  // --------------------------------------------------------------------------------
1841
  // Function : privOptionDefaultThreshold()
1842
  // Description :
1843
  // Parameters :
1844
  // Return Values :
1845
  // --------------------------------------------------------------------------------
1846
  function privOptionDefaultThreshold(&$p_options)
1847
  {
1848
    $v_result=1;
1849
1850
    if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1851
        || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1852
      return $v_result;
1853
    }
1854
1855
    // ----- Get 'memory_limit' configuration value
1856
    $v_memory_limit = ini_get('memory_limit');
1857
    $v_memory_limit = trim($v_memory_limit);
1858
    $last = strtolower(substr($v_memory_limit, -1));
1859
1860
    if($last == 'g')
1861
        //$v_memory_limit = $v_memory_limit*1024*1024*1024;
1862
        $v_memory_limit = $v_memory_limit*1073741824;
1863
    if($last == 'm')
1864
        //$v_memory_limit = $v_memory_limit*1024*1024;
1865
        $v_memory_limit = $v_memory_limit*1048576;
1866
    if($last == 'k')
1867
        $v_memory_limit = $v_memory_limit*1024;
1868
1869
    $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
1870
1871
1872
    // ----- Sanity check : No threshold if value lower than 1M
1873
    if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1874
      unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1875
    }
1876
1877
    // ----- Return
1878
    return $v_result;
1879
  }
1880
  // --------------------------------------------------------------------------------
1881
1882
  // --------------------------------------------------------------------------------
1883
  // Function : privFileDescrParseAtt()
1884
  // Description :
1885
  // Parameters :
1886
  // Return Values :
1887
  //   1 on success.
1888
  //   0 on failure.
1889
  // --------------------------------------------------------------------------------
1890
  function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1891
  {
1892
    $v_result=1;
1893
1894
    // ----- For each file in the list check the attributes
1895
    foreach ($p_file_list as $v_key => $v_value) {
1896
1897
      // ----- Check if the option is supported
1898 View Code Duplication
      if (!isset($v_requested_options[$v_key])) {
1899
        // ----- Error log
1900
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1901
1902
        // ----- Return
1903
        return PclZip::errorCode();
1904
      }
1905
1906
      // ----- Look for attribute
1907
      switch ($v_key) {
1908 View Code Duplication
        case PCLZIP_ATT_FILE_NAME :
1909
          if (!is_string($v_value)) {
1910
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1911
            return PclZip::errorCode();
1912
          }
1913
1914
          $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1915
1916
          if ($p_filedescr['filename'] == '') {
1917
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1918
            return PclZip::errorCode();
1919
          }
1920
1921
        break;
1922
1923 View Code Duplication
        case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1924
          if (!is_string($v_value)) {
1925
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1926
            return PclZip::errorCode();
1927
          }
1928
1929
          $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1930
1931
          if ($p_filedescr['new_short_name'] == '') {
1932
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1933
            return PclZip::errorCode();
1934
          }
1935
        break;
1936
1937 View Code Duplication
        case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1938
          if (!is_string($v_value)) {
1939
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1940
            return PclZip::errorCode();
1941
          }
1942
1943
          $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1944
1945
          if ($p_filedescr['new_full_name'] == '') {
1946
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1947
            return PclZip::errorCode();
1948
          }
1949
        break;
1950
1951
        // ----- Look for options that takes a string
1952 View Code Duplication
        case PCLZIP_ATT_FILE_COMMENT :
1953
          if (!is_string($v_value)) {
1954
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1955
            return PclZip::errorCode();
1956
          }
1957
1958
          $p_filedescr['comment'] = $v_value;
1959
        break;
1960
1961 View Code Duplication
        case PCLZIP_ATT_FILE_MTIME :
1962
          if (!is_integer($v_value)) {
1963
            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1964
            return PclZip::errorCode();
1965
          }
1966
1967
          $p_filedescr['mtime'] = $v_value;
1968
        break;
1969
1970
        case PCLZIP_ATT_FILE_CONTENT :
1971
          $p_filedescr['content'] = $v_value;
1972
        break;
1973
1974
        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...
1975
          // ----- Error log
1976
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1977
		                           "Unknown parameter '".$v_key."'");
1978
1979
          // ----- Return
1980
          return PclZip::errorCode();
1981
      }
1982
1983
      // ----- Look for mandatory options
1984 View Code Duplication
      if ($v_requested_options !== false) {
1985
        for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1986
          // ----- Look for mandatory option
1987
          if ($v_requested_options[$key] == 'mandatory') {
1988
            // ----- Look if present
1989
            if (!isset($p_file_list[$key])) {
1990
              PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1991
              return PclZip::errorCode();
1992
            }
1993
          }
1994
        }
1995
      }
1996
1997
    // end foreach
1998
    }
1999
2000
    // ----- Return
2001
    return $v_result;
2002
  }
2003
  // --------------------------------------------------------------------------------
2004
2005
  // --------------------------------------------------------------------------------
2006
  // Function : privFileDescrExpand()
2007
  // Description :
2008
  //   This method look for each item of the list to see if its a file, a folder
2009
  //   or a string to be added as file. For any other type of files (link, other)
2010
  //   just ignore the item.
2011
  //   Then prepare the information that will be stored for that file.
2012
  //   When its a folder, expand the folder with all the files that are in that
2013
  //   folder (recursively).
2014
  // Parameters :
2015
  // Return Values :
2016
  //   1 on success.
2017
  //   0 on failure.
2018
  // --------------------------------------------------------------------------------
2019
  function privFileDescrExpand(&$p_filedescr_list, &$p_options)
2020
  {
2021
    $v_result=1;
2022
2023
    // ----- Create a result list
2024
    $v_result_list = array();
2025
2026
    // ----- Look each entry
2027
    for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
2028
2029
      // ----- Get filedescr
2030
      $v_descr = $p_filedescr_list[$i];
2031
2032
      // ----- Reduce the filename
2033
      $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
2034
      $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
2035
2036
      // ----- Look for real file or folder
2037
      if (file_exists($v_descr['filename'])) {
2038
        if (@is_file($v_descr['filename'])) {
2039
          $v_descr['type'] = 'file';
2040
        }
2041
        else if (@is_dir($v_descr['filename'])) {
2042
          $v_descr['type'] = 'folder';
2043
        }
2044
        else if (@is_link($v_descr['filename'])) {
2045
          // skip
2046
          continue;
2047
        }
2048
        else {
2049
          // skip
2050
          continue;
2051
        }
2052
      }
2053
2054
      // ----- Look for string added as file
2055
      else if (isset($v_descr['content'])) {
2056
        $v_descr['type'] = 'virtual_file';
2057
      }
2058
2059
      // ----- Missing file
2060
      else {
2061
        // ----- Error log
2062
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
2063
2064
        // ----- Return
2065
        return PclZip::errorCode();
2066
      }
2067
2068
      // ----- Calculate the stored filename
2069
      $this->privCalculateStoredFilename($v_descr, $p_options);
2070
2071
      // ----- Add the descriptor in result list
2072
      $v_result_list[sizeof($v_result_list)] = $v_descr;
2073
2074
      // ----- Look for folder
2075
      if ($v_descr['type'] == 'folder') {
2076
        // ----- List of items in folder
2077
        $v_dirlist_descr = array();
2078
        $v_dirlist_nb = 0;
2079
        if ($v_folder_handler = @opendir($v_descr['filename'])) {
2080
          while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2081
2082
            // ----- Skip '.' and '..'
2083
            if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2084
                continue;
2085
            }
2086
2087
            // ----- Compose the full filename
2088
            $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2089
2090
            // ----- Look for different stored filename
2091
            // Because the name of the folder was changed, the name of the
2092
            // files/sub-folders also change
2093
            if (($v_descr['stored_filename'] != $v_descr['filename'])
2094
                 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2095
              if ($v_descr['stored_filename'] != '') {
2096
                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2097
              }
2098
              else {
2099
                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2100
              }
2101
            }
2102
2103
            $v_dirlist_nb++;
2104
          }
2105
2106
          @closedir($v_folder_handler);
2107
        }
2108
        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...
2109
          // TBC : unable to open folder in read mode
2110
        }
2111
2112
        // ----- Expand each element of the list
2113
        if ($v_dirlist_nb != 0) {
2114
          // ----- Expand
2115
          if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2116
            return $v_result;
2117
          }
2118
2119
          // ----- Concat the resulting list
2120
          $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2121
        }
2122
        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...
2123
        }
2124
2125
        // ----- Free local array
2126
        unset($v_dirlist_descr);
2127
      }
2128
    }
2129
2130
    // ----- Get the result list
2131
    $p_filedescr_list = $v_result_list;
2132
2133
    // ----- Return
2134
    return $v_result;
2135
  }
2136
  // --------------------------------------------------------------------------------
2137
2138
  // --------------------------------------------------------------------------------
2139
  // Function : privCreate()
2140
  // Description :
2141
  // Parameters :
2142
  // Return Values :
2143
  // --------------------------------------------------------------------------------
2144
  function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2145
  {
2146
    $v_result=1;
2147
    $v_list_detail = array();
2148
2149
    // ----- Magic quotes trick
2150
    $this->privDisableMagicQuotes();
2151
2152
    // ----- Open the file in write mode
2153
    if (($v_result = $this->privOpenFd('wb')) != 1)
2154
    {
2155
      // ----- Return
2156
      return $v_result;
2157
    }
2158
2159
    // ----- Add the list of files
2160
    $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2161
2162
    // ----- Close
2163
    $this->privCloseFd();
2164
2165
    // ----- Magic quotes trick
2166
    $this->privSwapBackMagicQuotes();
2167
2168
    // ----- Return
2169
    return $v_result;
2170
  }
2171
  // --------------------------------------------------------------------------------
2172
2173
  // --------------------------------------------------------------------------------
2174
  // Function : privAdd()
2175
  // Description :
2176
  // Parameters :
2177
  // Return Values :
2178
  // --------------------------------------------------------------------------------
2179
  function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2180
  {
2181
    $v_result=1;
2182
    $v_list_detail = array();
2183
2184
    // ----- Look if the archive exists or is empty
2185
    if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2186
    {
2187
2188
      // ----- Do a create
2189
      $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2190
2191
      // ----- Return
2192
      return $v_result;
2193
    }
2194
    // ----- Magic quotes trick
2195
    $this->privDisableMagicQuotes();
2196
2197
    // ----- Open the zip file
2198
    if (($v_result=$this->privOpenFd('rb')) != 1)
2199
    {
2200
      // ----- Magic quotes trick
2201
      $this->privSwapBackMagicQuotes();
2202
2203
      // ----- Return
2204
      return $v_result;
2205
    }
2206
2207
    // ----- Read the central directory informations
2208
    $v_central_dir = array();
2209
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2210
    {
2211
      $this->privCloseFd();
2212
      $this->privSwapBackMagicQuotes();
2213
      return $v_result;
2214
    }
2215
2216
    // ----- Go to beginning of File
2217
    @rewind($this->zip_fd);
2218
2219
    // ----- Creates a temporay file
2220
    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2221
2222
    // ----- Open the temporary file in write mode
2223
    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2224
    {
2225
      $this->privCloseFd();
2226
      $this->privSwapBackMagicQuotes();
2227
2228
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2229
2230
      // ----- Return
2231
      return PclZip::errorCode();
2232
    }
2233
2234
    // ----- Copy the files from the archive to the temporary file
2235
    // TBC : Here I should better append the file and go back to erase the central dir
2236
    $v_size = $v_central_dir['offset'];
2237
    while ($v_size != 0)
2238
    {
2239
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2240
      $v_buffer = fread($this->zip_fd, $v_read_size);
2241
      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2242
      $v_size -= $v_read_size;
2243
    }
2244
2245
    // ----- Swap the file descriptor
2246
    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2247
    // the following methods on the temporary fil and not the real archive
2248
    $v_swap = $this->zip_fd;
2249
    $this->zip_fd = $v_zip_temp_fd;
2250
    $v_zip_temp_fd = $v_swap;
2251
2252
    // ----- Add the files
2253
    $v_header_list = array();
2254 View Code Duplication
    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2255
    {
2256
      fclose($v_zip_temp_fd);
2257
      $this->privCloseFd();
2258
      @unlink($v_zip_temp_name);
2259
      $this->privSwapBackMagicQuotes();
2260
2261
      // ----- Return
2262
      return $v_result;
2263
    }
2264
2265
    // ----- Store the offset of the central dir
2266
    $v_offset = @ftell($this->zip_fd);
2267
2268
    // ----- Copy the block of file headers from the old archive
2269
    $v_size = $v_central_dir['size'];
2270 View Code Duplication
    while ($v_size != 0)
2271
    {
2272
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2273
      $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2274
      @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2275
      $v_size -= $v_read_size;
2276
    }
2277
2278
    // ----- Create the Central Dir files header
2279
    for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2280
    {
2281
      // ----- Create the file header
2282
      if ($v_header_list[$i]['status'] == 'ok') {
2283 View Code Duplication
        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2284
          fclose($v_zip_temp_fd);
2285
          $this->privCloseFd();
2286
          @unlink($v_zip_temp_name);
2287
          $this->privSwapBackMagicQuotes();
2288
2289
          // ----- Return
2290
          return $v_result;
2291
        }
2292
        $v_count++;
2293
      }
2294
2295
      // ----- Transform the header to a 'usable' info
2296
      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2297
    }
2298
2299
    // ----- Zip file comment
2300
    $v_comment = $v_central_dir['comment'];
2301
    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2302
      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2303
    }
2304
    if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2305
      $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2306
    }
2307
    if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2308
      $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2309
    }
2310
2311
    // ----- Calculate the size of the central header
2312
    $v_size = @ftell($this->zip_fd)-$v_offset;
2313
2314
    // ----- Create the central dir footer
2315
    if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2316
    {
2317
      // ----- Reset the file list
2318
      unset($v_header_list);
2319
      $this->privSwapBackMagicQuotes();
2320
2321
      // ----- Return
2322
      return $v_result;
2323
    }
2324
2325
    // ----- Swap back the file descriptor
2326
    $v_swap = $this->zip_fd;
2327
    $this->zip_fd = $v_zip_temp_fd;
2328
    $v_zip_temp_fd = $v_swap;
2329
2330
    // ----- Close
2331
    $this->privCloseFd();
2332
2333
    // ----- Close the temporary file
2334
    @fclose($v_zip_temp_fd);
2335
2336
    // ----- Magic quotes trick
2337
    $this->privSwapBackMagicQuotes();
2338
2339
    // ----- Delete the zip file
2340
    // TBC : I should test the result ...
2341
    @unlink($this->zipname);
2342
2343
    // ----- Rename the temporary file
2344
    // TBC : I should test the result ...
2345
    //@rename($v_zip_temp_name, $this->zipname);
2346
    PclZipUtilRename($v_zip_temp_name, $this->zipname);
2347
2348
    // ----- Return
2349
    return $v_result;
2350
  }
2351
  // --------------------------------------------------------------------------------
2352
2353
  // --------------------------------------------------------------------------------
2354
  // Function : privOpenFd()
2355
  // Description :
2356
  // Parameters :
2357
  // --------------------------------------------------------------------------------
2358
  function privOpenFd($p_mode)
2359
  {
2360
    $v_result=1;
2361
2362
    // ----- Look if already open
2363
    if ($this->zip_fd != 0)
2364
    {
2365
      // ----- Error log
2366
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2367
2368
      // ----- Return
2369
      return PclZip::errorCode();
2370
    }
2371
2372
    // ----- Open the zip file
2373
    if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2374
    {
2375
      // ----- Error log
2376
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2377
2378
      // ----- Return
2379
      return PclZip::errorCode();
2380
    }
2381
2382
    // ----- Return
2383
    return $v_result;
2384
  }
2385
  // --------------------------------------------------------------------------------
2386
2387
  // --------------------------------------------------------------------------------
2388
  // Function : privCloseFd()
2389
  // Description :
2390
  // Parameters :
2391
  // --------------------------------------------------------------------------------
2392
  function privCloseFd()
2393
  {
2394
    $v_result=1;
2395
2396
    if ($this->zip_fd != 0)
2397
      @fclose($this->zip_fd);
2398
    $this->zip_fd = 0;
2399
2400
    // ----- Return
2401
    return $v_result;
2402
  }
2403
  // --------------------------------------------------------------------------------
2404
2405
  // --------------------------------------------------------------------------------
2406
  // Function : privAddList()
2407
  // Description :
2408
  //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2409
  //   different from the real path of the file. This is usefull if you want to have PclTar
2410
  //   running in any directory, and memorize relative path from an other directory.
2411
  // Parameters :
2412
  //   $p_list : An array containing the file or directory names to add in the tar
2413
  //   $p_result_list : list of added files with their properties (specially the status field)
2414
  //   $p_add_dir : Path to add in the filename path archived
2415
  //   $p_remove_dir : Path to remove in the filename path archived
2416
  // Return Values :
2417
  // --------------------------------------------------------------------------------
2418
//  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2419
  function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2420
  {
2421
    $v_result=1;
2422
2423
    // ----- Add the files
2424
    $v_header_list = array();
2425
    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2426
    {
2427
      // ----- Return
2428
      return $v_result;
2429
    }
2430
2431
    // ----- Store the offset of the central dir
2432
    $v_offset = @ftell($this->zip_fd);
2433
2434
    // ----- Create the Central Dir files header
2435
    for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2436
    {
2437
      // ----- Create the file header
2438
      if ($v_header_list[$i]['status'] == 'ok') {
2439
        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2440
          // ----- Return
2441
          return $v_result;
2442
        }
2443
        $v_count++;
2444
      }
2445
2446
      // ----- Transform the header to a 'usable' info
2447
      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2448
    }
2449
2450
    // ----- Zip file comment
2451
    $v_comment = '';
2452
    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2453
      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2454
    }
2455
2456
    // ----- Calculate the size of the central header
2457
    $v_size = @ftell($this->zip_fd)-$v_offset;
2458
2459
    // ----- Create the central dir footer
2460
    if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2461
    {
2462
      // ----- Reset the file list
2463
      unset($v_header_list);
2464
2465
      // ----- Return
2466
      return $v_result;
2467
    }
2468
2469
    // ----- Return
2470
    return $v_result;
2471
  }
2472
  // --------------------------------------------------------------------------------
2473
2474
  // --------------------------------------------------------------------------------
2475
  // Function : privAddFileList()
2476
  // Description :
2477
  // Parameters :
2478
  //   $p_filedescr_list : An array containing the file description
2479
  //                      or directory names to add in the zip
2480
  //   $p_result_list : list of added files with their properties (specially the status field)
2481
  // Return Values :
2482
  // --------------------------------------------------------------------------------
2483
  function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2484
  {
2485
    $v_result=1;
2486
    $v_header = array();
2487
2488
    // ----- Recuperate the current number of elt in list
2489
    $v_nb = sizeof($p_result_list);
2490
2491
    // ----- Loop on the files
2492
    for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2493
      // ----- Format the filename
2494
      $p_filedescr_list[$j]['filename']
2495
      = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2496
2497
2498
      // ----- Skip empty file names
2499
      // TBC : Can this be possible ? not checked in DescrParseAtt ?
2500
      if ($p_filedescr_list[$j]['filename'] == "") {
2501
        continue;
2502
      }
2503
2504
      // ----- Check the filename
2505
      if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')
2506
          && (!file_exists($p_filedescr_list[$j]['filename']))) {
2507
        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
2508
        return PclZip::errorCode();
2509
      }
2510
2511
      // ----- Look if it is a file or a dir with no all path remove option
2512
      // or a dir with all its path removed
2513
//      if (   (is_file($p_filedescr_list[$j]['filename']))
2514
//          || (   is_dir($p_filedescr_list[$j]['filename'])
2515
      if (   ($p_filedescr_list[$j]['type'] == 'file')
2516
          || ($p_filedescr_list[$j]['type'] == 'virtual_file')
2517
          || (   ($p_filedescr_list[$j]['type'] == 'folder')
2518
              && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2519
                  || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
2520
          ) {
2521
2522
        // ----- Add the file
2523
        $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2524
                                       $p_options);
2525
        if ($v_result != 1) {
2526
          return $v_result;
2527
        }
2528
2529
        // ----- Store the file infos
2530
        $p_result_list[$v_nb++] = $v_header;
2531
      }
2532
    }
2533
2534
    // ----- Return
2535
    return $v_result;
2536
  }
2537
  // --------------------------------------------------------------------------------
2538
2539
  // --------------------------------------------------------------------------------
2540
  // Function : privAddFile()
2541
  // Description :
2542
  // Parameters :
2543
  // Return Values :
2544
  // --------------------------------------------------------------------------------
2545
  function privAddFile($p_filedescr, &$p_header, &$p_options)
2546
  {
2547
    $v_result=1;
2548
2549
    // ----- Working variable
2550
    $p_filename = $p_filedescr['filename'];
2551
2552
    // TBC : Already done in the fileAtt check ... ?
2553
    if ($p_filename == "") {
2554
      // ----- Error log
2555
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2556
2557
      // ----- Return
2558
      return PclZip::errorCode();
2559
    }
2560
2561
    // ----- Look for a stored different filename
2562
    /* TBC : Removed
2563
    if (isset($p_filedescr['stored_filename'])) {
2564
      $v_stored_filename = $p_filedescr['stored_filename'];
2565
    }
2566
    else {
2567
      $v_stored_filename = $p_filedescr['stored_filename'];
2568
    }
2569
    */
2570
2571
    // ----- Set the file properties
2572
    clearstatcache();
2573
    $p_header['version'] = 20;
2574
    $p_header['version_extracted'] = 10;
2575
    $p_header['flag'] = 0;
2576
    $p_header['compression'] = 0;
2577
    $p_header['crc'] = 0;
2578
    $p_header['compressed_size'] = 0;
2579
    $p_header['filename_len'] = strlen($p_filename);
2580
    $p_header['extra_len'] = 0;
2581
    $p_header['disk'] = 0;
2582
    $p_header['internal'] = 0;
2583
    $p_header['offset'] = 0;
2584
    $p_header['filename'] = $p_filename;
2585
// TBC : Removed    $p_header['stored_filename'] = $v_stored_filename;
2586
    $p_header['stored_filename'] = $p_filedescr['stored_filename'];
2587
    $p_header['extra'] = '';
2588
    $p_header['status'] = 'ok';
2589
    $p_header['index'] = -1;
2590
2591
    // ----- Look for regular file
2592
    if ($p_filedescr['type']=='file') {
2593
      $p_header['external'] = 0x00000000;
2594
      $p_header['size'] = filesize($p_filename);
2595
    }
2596
2597
    // ----- Look for regular folder
2598
    else if ($p_filedescr['type']=='folder') {
2599
      $p_header['external'] = 0x00000010;
2600
      $p_header['mtime'] = filemtime($p_filename);
2601
      $p_header['size'] = filesize($p_filename);
2602
    }
2603
2604
    // ----- Look for virtual file
2605
    else if ($p_filedescr['type'] == 'virtual_file') {
2606
      $p_header['external'] = 0x00000000;
2607
      $p_header['size'] = strlen($p_filedescr['content']);
2608
    }
2609
2610
2611
    // ----- Look for filetime
2612
    if (isset($p_filedescr['mtime'])) {
2613
      $p_header['mtime'] = $p_filedescr['mtime'];
2614
    }
2615
    else if ($p_filedescr['type'] == 'virtual_file') {
2616
      $p_header['mtime'] = time();
2617
    }
2618
    else {
2619
      $p_header['mtime'] = filemtime($p_filename);
2620
    }
2621
2622
    // ------ Look for file comment
2623
    if (isset($p_filedescr['comment'])) {
2624
      $p_header['comment_len'] = strlen($p_filedescr['comment']);
2625
      $p_header['comment'] = $p_filedescr['comment'];
2626
    }
2627
    else {
2628
      $p_header['comment_len'] = 0;
2629
      $p_header['comment'] = '';
2630
    }
2631
2632
    // ----- Look for pre-add callback
2633
    if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2634
2635
      // ----- Generate a local information
2636
      $v_local_header = array();
2637
      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2638
2639
      // ----- Call the callback
2640
      // Here I do not use call_user_func() because I need to send a reference to the
2641
      // header.
2642
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2643
      $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2644
      if ($v_result == 0) {
2645
        // ----- Change the file status
2646
        $p_header['status'] = "skipped";
2647
        $v_result = 1;
2648
      }
2649
2650
      // ----- Update the informations
2651
      // Only some fields can be modified
2652
      if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2653
        $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2654
      }
2655
    }
2656
2657
    // ----- Look for empty stored filename
2658
    if ($p_header['stored_filename'] == "") {
2659
      $p_header['status'] = "filtered";
2660
    }
2661
2662
    // ----- Check the path length
2663
    if (strlen($p_header['stored_filename']) > 0xFF) {
2664
      $p_header['status'] = 'filename_too_long';
2665
    }
2666
2667
    // ----- Look if no error, or file not skipped
2668
    if ($p_header['status'] == 'ok') {
2669
2670
      // ----- Look for a file
2671
      if ($p_filedescr['type'] == 'file') {
2672
        // ----- Look for using temporary file to zip
2673
        if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
2674
            && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2675
                || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2676
                    && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
2677
          $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2678
          if ($v_result < PCLZIP_ERR_NO_ERROR) {
2679
            return $v_result;
2680
          }
2681
        }
2682
2683
        // ----- Use "in memory" zip algo
2684
        else {
2685
2686
        // ----- Open the source file
2687 View Code Duplication
        if (($v_file = @fopen($p_filename, "rb")) == 0) {
2688
          PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2689
          return PclZip::errorCode();
2690
        }
2691
2692
        // ----- Read the file content
2693
        $v_content = @fread($v_file, $p_header['size']);
2694
2695
        // ----- Close the file
2696
        @fclose($v_file);
2697
2698
        // ----- Calculate the CRC
2699
        $p_header['crc'] = @crc32($v_content);
2700
2701
        // ----- Look for no compression
2702 View Code Duplication
        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2703
          // ----- Set header parameters
2704
          $p_header['compressed_size'] = $p_header['size'];
2705
          $p_header['compression'] = 0;
2706
        }
2707
2708
        // ----- Look for normal compression
2709
        else {
2710
          // ----- Compress the content
2711
          $v_content = @gzdeflate($v_content);
2712
2713
          // ----- Set header parameters
2714
          $p_header['compressed_size'] = strlen($v_content);
2715
          $p_header['compression'] = 8;
2716
        }
2717
2718
        // ----- Call the header generation
2719
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2720
          @fclose($v_file);
2721
          return $v_result;
2722
        }
2723
2724
        // ----- Write the compressed (or not) content
2725
        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2726
2727
        }
2728
2729
      }
2730
2731
      // ----- Look for a virtual file (a file from string)
2732
      else if ($p_filedescr['type'] == 'virtual_file') {
2733
2734
        $v_content = $p_filedescr['content'];
2735
2736
        // ----- Calculate the CRC
2737
        $p_header['crc'] = @crc32($v_content);
2738
2739
        // ----- Look for no compression
2740 View Code Duplication
        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2741
          // ----- Set header parameters
2742
          $p_header['compressed_size'] = $p_header['size'];
2743
          $p_header['compression'] = 0;
2744
        }
2745
2746
        // ----- Look for normal compression
2747
        else {
2748
          // ----- Compress the content
2749
          $v_content = @gzdeflate($v_content);
2750
2751
          // ----- Set header parameters
2752
          $p_header['compressed_size'] = strlen($v_content);
2753
          $p_header['compression'] = 8;
2754
        }
2755
2756
        // ----- Call the header generation
2757
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2758
          @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...
2759
          return $v_result;
2760
        }
2761
2762
        // ----- Write the compressed (or not) content
2763
        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2764
      }
2765
2766
      // ----- Look for a directory
2767
      else if ($p_filedescr['type'] == 'folder') {
2768
        // ----- Look for directory last '/'
2769
        if (@substr($p_header['stored_filename'], -1) != '/') {
2770
          $p_header['stored_filename'] .= '/';
2771
        }
2772
2773
        // ----- Set the file properties
2774
        $p_header['size'] = 0;
2775
        //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
2776
        $p_header['external'] = 0x00000010;   // Value for a folder : to be checked
2777
2778
        // ----- Call the header generation
2779
        if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2780
        {
2781
          return $v_result;
2782
        }
2783
      }
2784
    }
2785
2786
    // ----- Look for post-add callback
2787
    if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2788
2789
      // ----- Generate a local information
2790
      $v_local_header = array();
2791
      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2792
2793
      // ----- Call the callback
2794
      // Here I do not use call_user_func() because I need to send a reference to the
2795
      // header.
2796
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2797
      $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2798
      if ($v_result == 0) {
2799
        // ----- Ignored
2800
        $v_result = 1;
2801
      }
2802
2803
      // ----- Update the informations
2804
      // Nothing can be modified
2805
    }
2806
2807
    // ----- Return
2808
    return $v_result;
2809
  }
2810
  // --------------------------------------------------------------------------------
2811
2812
  // --------------------------------------------------------------------------------
2813
  // Function : privAddFileUsingTempFile()
2814
  // Description :
2815
  // Parameters :
2816
  // Return Values :
2817
  // --------------------------------------------------------------------------------
2818
  function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
2819
  {
2820
    $v_result=PCLZIP_ERR_NO_ERROR;
2821
2822
    // ----- Working variable
2823
    $p_filename = $p_filedescr['filename'];
2824
2825
2826
    // ----- Open the source file
2827 View Code Duplication
    if (($v_file = @fopen($p_filename, "rb")) == 0) {
2828
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2829
      return PclZip::errorCode();
2830
    }
2831
2832
    // ----- Creates a compressed temporary file
2833
    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2834 View Code Duplication
    if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2835
      fclose($v_file);
2836
      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2837
      return PclZip::errorCode();
2838
    }
2839
2840
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2841
    $v_size = filesize($p_filename);
2842
    while ($v_size != 0) {
2843
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2844
      $v_buffer = @fread($v_file, $v_read_size);
2845
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2846
      @gzputs($v_file_compressed, $v_buffer, $v_read_size);
2847
      $v_size -= $v_read_size;
2848
    }
2849
2850
    // ----- Close the file
2851
    @fclose($v_file);
2852
    @gzclose($v_file_compressed);
2853
2854
    // ----- Check the minimum file size
2855 View Code Duplication
    if (filesize($v_gzip_temp_name) < 18) {
2856
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
2857
      return PclZip::errorCode();
2858
    }
2859
2860
    // ----- Extract the compressed attributes
2861 View Code Duplication
    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2862
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2863
      return PclZip::errorCode();
2864
    }
2865
2866
    // ----- Read the gzip file header
2867
    $v_binary_data = @fread($v_file_compressed, 10);
2868
    $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
2869
2870
    // ----- Check some parameters
2871
    $v_data_header['os'] = bin2hex($v_data_header['os']);
2872
2873
    // ----- Read the gzip file footer
2874
    @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
2875
    $v_binary_data = @fread($v_file_compressed, 8);
2876
    $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2877
2878
    // ----- Set the attributes
2879
    $p_header['compression'] = ord($v_data_header['cm']);
2880
    //$p_header['mtime'] = $v_data_header['mtime'];
2881
    $p_header['crc'] = $v_data_footer['crc'];
2882
    $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
2883
2884
    // ----- Close the file
2885
    @fclose($v_file_compressed);
2886
2887
    // ----- Call the header generation
2888
    if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2889
      return $v_result;
2890
    }
2891
2892
    // ----- Add the compressed data
2893 View Code Duplication
    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
2894
    {
2895
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2896
      return PclZip::errorCode();
2897
    }
2898
2899
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2900
    fseek($v_file_compressed, 10);
2901
    $v_size = $p_header['compressed_size'];
2902 View Code Duplication
    while ($v_size != 0)
2903
    {
2904
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2905
      $v_buffer = @fread($v_file_compressed, $v_read_size);
2906
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2907
      @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2908
      $v_size -= $v_read_size;
2909
    }
2910
2911
    // ----- Close the file
2912
    @fclose($v_file_compressed);
2913
2914
    // ----- Unlink the temporary file
2915
    @unlink($v_gzip_temp_name);
2916
2917
    // ----- Return
2918
    return $v_result;
2919
  }
2920
  // --------------------------------------------------------------------------------
2921
2922
  // --------------------------------------------------------------------------------
2923
  // Function : privCalculateStoredFilename()
2924
  // Description :
2925
  //   Based on file descriptor properties and global options, this method
2926
  //   calculate the filename that will be stored in the archive.
2927
  // Parameters :
2928
  // Return Values :
2929
  // --------------------------------------------------------------------------------
2930
  function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2931
  {
2932
    $v_result=1;
2933
2934
    // ----- Working variables
2935
    $p_filename = $p_filedescr['filename'];
2936
    if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2937
      $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2938
    }
2939
    else {
2940
      $p_add_dir = '';
2941
    }
2942
    if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2943
      $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2944
    }
2945
    else {
2946
      $p_remove_dir = '';
2947
    }
2948
    if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2949
      $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2950
    }
2951
    else {
2952
      $p_remove_all_dir = 0;
2953
    }
2954
2955
2956
    // ----- Look for full name change
2957
    if (isset($p_filedescr['new_full_name'])) {
2958
      // ----- Remove drive letter if any
2959
      $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2960
    }
2961
2962
    // ----- Look for path and/or short name change
2963
    else {
2964
2965
      // ----- Look for short name change
2966
      // Its when we cahnge just the filename but not the path
2967
      if (isset($p_filedescr['new_short_name'])) {
2968
        $v_path_info = pathinfo($p_filename);
2969
        $v_dir = '';
2970
        if ($v_path_info['dirname'] != '') {
2971
          $v_dir = $v_path_info['dirname'].'/';
2972
        }
2973
        $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2974
      }
2975
      else {
2976
        // ----- Calculate the stored filename
2977
        $v_stored_filename = $p_filename;
2978
      }
2979
2980
      // ----- Look for all path to remove
2981
      if ($p_remove_all_dir) {
2982
        $v_stored_filename = basename($p_filename);
2983
      }
2984
      // ----- Look for partial path remove
2985
      else if ($p_remove_dir != "") {
2986
        if (substr($p_remove_dir, -1) != '/')
2987
          $p_remove_dir .= "/";
2988
2989
        if (   (substr($p_filename, 0, 2) == "./")
2990
            || (substr($p_remove_dir, 0, 2) == "./")) {
2991
2992 View Code Duplication
          if (   (substr($p_filename, 0, 2) == "./")
2993
              && (substr($p_remove_dir, 0, 2) != "./")) {
2994
            $p_remove_dir = "./".$p_remove_dir;
2995
          }
2996 View Code Duplication
          if (   (substr($p_filename, 0, 2) != "./")
2997
              && (substr($p_remove_dir, 0, 2) == "./")) {
2998
            $p_remove_dir = substr($p_remove_dir, 2);
2999
          }
3000
        }
3001
3002
        $v_compare = PclZipUtilPathInclusion($p_remove_dir,
3003
                                             $v_stored_filename);
3004
        if ($v_compare > 0) {
3005
          if ($v_compare == 2) {
3006
            $v_stored_filename = "";
3007
          }
3008
          else {
3009
            $v_stored_filename = substr($v_stored_filename,
3010
                                        strlen($p_remove_dir));
3011
          }
3012
        }
3013
      }
3014
3015
      // ----- Remove drive letter if any
3016
      $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
3017
3018
      // ----- Look for path to add
3019
      if ($p_add_dir != "") {
3020
        if (substr($p_add_dir, -1) == "/")
3021
          $v_stored_filename = $p_add_dir.$v_stored_filename;
3022
        else
3023
          $v_stored_filename = $p_add_dir."/".$v_stored_filename;
3024
      }
3025
    }
3026
3027
    // ----- Filename (reduce the path of stored name)
3028
    $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
3029
    $p_filedescr['stored_filename'] = $v_stored_filename;
3030
3031
    // ----- Return
3032
    return $v_result;
3033
  }
3034
  // --------------------------------------------------------------------------------
3035
3036
  // --------------------------------------------------------------------------------
3037
  // Function : privWriteFileHeader()
3038
  // Description :
3039
  // Parameters :
3040
  // Return Values :
3041
  // --------------------------------------------------------------------------------
3042
  function privWriteFileHeader(&$p_header)
3043
  {
3044
    $v_result=1;
3045
3046
    // ----- Store the offset position of the file
3047
    $p_header['offset'] = ftell($this->zip_fd);
3048
3049
    // ----- Transform UNIX mtime to DOS format mdate/mtime
3050
    $v_date = getdate($p_header['mtime']);
3051
    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3052
    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3053
3054
    // ----- Packed data
3055
    $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
3056
	                      $p_header['version_extracted'], $p_header['flag'],
3057
                          $p_header['compression'], $v_mtime, $v_mdate,
3058
                          $p_header['crc'], $p_header['compressed_size'],
3059
						  $p_header['size'],
3060
                          strlen($p_header['stored_filename']),
3061
						  $p_header['extra_len']);
3062
3063
    // ----- Write the first 148 bytes of the header in the archive
3064
    fputs($this->zip_fd, $v_binary_data, 30);
3065
3066
    // ----- Write the variable fields
3067 View Code Duplication
    if (strlen($p_header['stored_filename']) != 0)
3068
    {
3069
      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3070
    }
3071 View Code Duplication
    if ($p_header['extra_len'] != 0)
3072
    {
3073
      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3074
    }
3075
3076
    // ----- Return
3077
    return $v_result;
3078
  }
3079
  // --------------------------------------------------------------------------------
3080
3081
  // --------------------------------------------------------------------------------
3082
  // Function : privWriteCentralFileHeader()
3083
  // Description :
3084
  // Parameters :
3085
  // Return Values :
3086
  // --------------------------------------------------------------------------------
3087
  function privWriteCentralFileHeader(&$p_header)
3088
  {
3089
    $v_result=1;
3090
3091
    // TBC
3092
    //for(reset($p_header); $key = key($p_header); next($p_header)) {
3093
    //}
3094
3095
    // ----- Transform UNIX mtime to DOS format mdate/mtime
3096
    $v_date = getdate($p_header['mtime']);
3097
    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3098
    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3099
3100
3101
    // ----- Packed data
3102
    $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
3103
	                      $p_header['version'], $p_header['version_extracted'],
3104
                          $p_header['flag'], $p_header['compression'],
3105
						  $v_mtime, $v_mdate, $p_header['crc'],
3106
                          $p_header['compressed_size'], $p_header['size'],
3107
                          strlen($p_header['stored_filename']),
3108
						  $p_header['extra_len'], $p_header['comment_len'],
3109
                          $p_header['disk'], $p_header['internal'],
3110
						  $p_header['external'], $p_header['offset']);
3111
3112
    // ----- Write the 42 bytes of the header in the zip file
3113
    fputs($this->zip_fd, $v_binary_data, 46);
3114
3115
    // ----- Write the variable fields
3116 View Code Duplication
    if (strlen($p_header['stored_filename']) != 0)
3117
    {
3118
      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3119
    }
3120 View Code Duplication
    if ($p_header['extra_len'] != 0)
3121
    {
3122
      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3123
    }
3124
    if ($p_header['comment_len'] != 0)
3125
    {
3126
      fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
3127
    }
3128
3129
    // ----- Return
3130
    return $v_result;
3131
  }
3132
  // --------------------------------------------------------------------------------
3133
3134
  // --------------------------------------------------------------------------------
3135
  // Function : privWriteCentralHeader()
3136
  // Description :
3137
  // Parameters :
3138
  // Return Values :
3139
  // --------------------------------------------------------------------------------
3140
  function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3141
  {
3142
    $v_result=1;
3143
3144
    // ----- Packed data
3145
    $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
3146
	                      $p_nb_entries, $p_size,
3147
						  $p_offset, strlen($p_comment));
3148
3149
    // ----- Write the 22 bytes of the header in the zip file
3150
    fputs($this->zip_fd, $v_binary_data, 22);
3151
3152
    // ----- Write the variable fields
3153
    if (strlen($p_comment) != 0)
3154
    {
3155
      fputs($this->zip_fd, $p_comment, strlen($p_comment));
3156
    }
3157
3158
    // ----- Return
3159
    return $v_result;
3160
  }
3161
  // --------------------------------------------------------------------------------
3162
3163
  // --------------------------------------------------------------------------------
3164
  // Function : privList()
3165
  // Description :
3166
  // Parameters :
3167
  // Return Values :
3168
  // --------------------------------------------------------------------------------
3169
  function privList(&$p_list)
3170
  {
3171
    $v_result=1;
3172
3173
    // ----- Magic quotes trick
3174
    $this->privDisableMagicQuotes();
3175
3176
    // ----- Open the zip file
3177 View Code Duplication
    if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
3178
    {
3179
      // ----- Magic quotes trick
3180
      $this->privSwapBackMagicQuotes();
3181
3182
      // ----- Error log
3183
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
3184
3185
      // ----- Return
3186
      return PclZip::errorCode();
3187
    }
3188
3189
    // ----- Read the central directory informations
3190
    $v_central_dir = array();
3191
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3192
    {
3193
      $this->privSwapBackMagicQuotes();
3194
      return $v_result;
3195
    }
3196
3197
    // ----- Go to beginning of Central Dir
3198
    @rewind($this->zip_fd);
3199 View Code Duplication
    if (@fseek($this->zip_fd, $v_central_dir['offset']))
3200
    {
3201
      $this->privSwapBackMagicQuotes();
3202
3203
      // ----- Error log
3204
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3205
3206
      // ----- Return
3207
      return PclZip::errorCode();
3208
    }
3209
3210
    // ----- Read each entry
3211
    for ($i=0; $i<$v_central_dir['entries']; $i++)
3212
    {
3213
      // ----- Read the file header
3214
      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3215
      {
3216
        $this->privSwapBackMagicQuotes();
3217
        return $v_result;
3218
      }
3219
      $v_header['index'] = $i;
3220
3221
      // ----- Get the only interesting attributes
3222
      $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3223
      unset($v_header);
3224
    }
3225
3226
    // ----- Close the zip file
3227
    $this->privCloseFd();
3228
3229
    // ----- Magic quotes trick
3230
    $this->privSwapBackMagicQuotes();
3231
3232
    // ----- Return
3233
    return $v_result;
3234
  }
3235
  // --------------------------------------------------------------------------------
3236
3237
  // --------------------------------------------------------------------------------
3238
  // Function : privConvertHeader2FileInfo()
3239
  // Description :
3240
  //   This function takes the file informations from the central directory
3241
  //   entries and extract the interesting parameters that will be given back.
3242
  //   The resulting file infos are set in the array $p_info
3243
  //     $p_info['filename'] : Filename with full path. Given by user (add),
3244
  //                           extracted in the filesystem (extract).
3245
  //     $p_info['stored_filename'] : Stored filename in the archive.
3246
  //     $p_info['size'] = Size of the file.
3247
  //     $p_info['compressed_size'] = Compressed size of the file.
3248
  //     $p_info['mtime'] = Last modification date of the file.
3249
  //     $p_info['comment'] = Comment associated with the file.
3250
  //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3251
  //     $p_info['status'] = status of the action on the file.
3252
  //     $p_info['crc'] = CRC of the file content.
3253
  // Parameters :
3254
  // Return Values :
3255
  // --------------------------------------------------------------------------------
3256
  function privConvertHeader2FileInfo($p_header, &$p_info)
3257
  {
3258
    $v_result=1;
3259
3260
    // ----- Get the interesting attributes
3261
    $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
3262
    $p_info['filename'] = $v_temp_path;
3263
    $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
3264
    $p_info['stored_filename'] = $v_temp_path;
3265
    $p_info['size'] = $p_header['size'];
3266
    $p_info['compressed_size'] = $p_header['compressed_size'];
3267
    $p_info['mtime'] = $p_header['mtime'];
3268
    $p_info['comment'] = $p_header['comment'];
3269
    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3270
    $p_info['index'] = $p_header['index'];
3271
    $p_info['status'] = $p_header['status'];
3272
    $p_info['crc'] = $p_header['crc'];
3273
3274
    // ----- Return
3275
    return $v_result;
3276
  }
3277
  // --------------------------------------------------------------------------------
3278
3279
  // --------------------------------------------------------------------------------
3280
  // Function : privExtractByRule()
3281
  // Description :
3282
  //   Extract a file or directory depending of rules (by index, by name, ...)
3283
  // Parameters :
3284
  //   $p_file_list : An array where will be placed the properties of each
3285
  //                  extracted file
3286
  //   $p_path : Path to add while writing the extracted files
3287
  //   $p_remove_path : Path to remove (from the file memorized path) while writing the
3288
  //                    extracted files. If the path does not match the file path,
3289
  //                    the file is extracted with its memorized path.
3290
  //                    $p_remove_path does not apply to 'list' mode.
3291
  //                    $p_path and $p_remove_path are commulative.
3292
  // Return Values :
3293
  //   1 on success,0 or less on error (see error code list)
3294
  // --------------------------------------------------------------------------------
3295
  function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3296
  {
3297
    $v_result=1;
3298
3299
    // ----- Magic quotes trick
3300
    $this->privDisableMagicQuotes();
3301
3302
    // ----- Check the path
3303
    if (   ($p_path == "")
3304
	    || (   (substr($p_path, 0, 1) != "/")
3305
		    && (substr($p_path, 0, 3) != "../")
3306
			&& (substr($p_path,1,2)!=":/")))
3307
      $p_path = "./".$p_path;
3308
3309
    // ----- Reduce the path last (and duplicated) '/'
3310
    if (($p_path != "./") && ($p_path != "/"))
3311
    {
3312
      // ----- Look for the path end '/'
3313 View Code Duplication
      while (substr($p_path, -1) == "/")
3314
      {
3315
        $p_path = substr($p_path, 0, strlen($p_path)-1);
3316
      }
3317
    }
3318
3319
    // ----- Look for path to remove format (should end by /)
3320
    if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3321
    {
3322
      $p_remove_path .= '/';
3323
    }
3324
    $p_remove_path_size = strlen($p_remove_path);
3325
3326
    // ----- Open the zip file
3327
    if (($v_result = $this->privOpenFd('rb')) != 1)
3328
    {
3329
      $this->privSwapBackMagicQuotes();
3330
      return $v_result;
3331
    }
3332
3333
    // ----- Read the central directory informations
3334
    $v_central_dir = array();
3335
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3336
    {
3337
      // ----- Close the zip file
3338
      $this->privCloseFd();
3339
      $this->privSwapBackMagicQuotes();
3340
3341
      return $v_result;
3342
    }
3343
3344
    // ----- Start at beginning of Central Dir
3345
    $v_pos_entry = $v_central_dir['offset'];
3346
3347
    // ----- Read each entry
3348
    $j_start = 0;
3349
    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3350
    {
3351
3352
      // ----- Read next Central dir entry
3353
      @rewind($this->zip_fd);
3354 View Code Duplication
      if (@fseek($this->zip_fd, $v_pos_entry))
3355
      {
3356
        // ----- Close the zip file
3357
        $this->privCloseFd();
3358
        $this->privSwapBackMagicQuotes();
3359
3360
        // ----- Error log
3361
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3362
3363
        // ----- Return
3364
        return PclZip::errorCode();
3365
      }
3366
3367
      // ----- Read the file header
3368
      $v_header = array();
3369
      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3370
      {
3371
        // ----- Close the zip file
3372
        $this->privCloseFd();
3373
        $this->privSwapBackMagicQuotes();
3374
3375
        return $v_result;
3376
      }
3377
3378
      // ----- Store the index
3379
      $v_header['index'] = $i;
3380
3381
      // ----- Store the file position
3382
      $v_pos_entry = ftell($this->zip_fd);
3383
3384
      // ----- Look for the specific extract rules
3385
      $v_extract = false;
3386
3387
      // ----- Look for extract by name rule
3388
      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
3389
          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3390
3391
          // ----- Look if the filename is in the list
3392
          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3393
3394
              // ----- Look for a directory
3395
              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3396
3397
                  // ----- Look if the directory is in the filename path
3398
                  if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3399
                      && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3400
                      $v_extract = true;
3401
                  }
3402
              }
3403
              // ----- Look for a filename
3404
              elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3405
                  $v_extract = true;
3406
              }
3407
          }
3408
      }
3409
3410
      // ----- Look for extract by ereg rule
3411
      // ereg() is deprecated with PHP 5.3
3412
      /*
3413
      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
3414
               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3415
3416
          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3417
              $v_extract = true;
3418
          }
3419
      }
3420
      */
3421
3422
      // ----- Look for extract by preg rule
3423 View Code Duplication
      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
3424
               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3425
3426
          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3427
              $v_extract = true;
3428
          }
3429
      }
3430
3431
      // ----- Look for extract by index rule
3432
      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3433
               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3434
3435
          // ----- Look if the index is in the list
3436
          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3437
3438
              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3439
                  $v_extract = true;
3440
              }
3441
              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3442
                  $j_start = $j+1;
3443
              }
3444
3445
              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3446
                  break;
3447
              }
3448
          }
3449
      }
3450
3451
      // ----- Look for no rule, which means extract all the archive
3452
      else {
3453
          $v_extract = true;
3454
      }
3455
3456
	  // ----- Check compression method
3457
	  if (   ($v_extract)
3458
	      && (   ($v_header['compression'] != 8)
3459
		      && ($v_header['compression'] != 0))) {
3460
          $v_header['status'] = 'unsupported_compression';
3461
3462
          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3463
          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3464
		      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3465
3466
              $this->privSwapBackMagicQuotes();
3467
3468
              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3469
			                       "Filename '".$v_header['stored_filename']."' is "
3470
				  	    	  	   ."compressed by an unsupported compression "
3471
				  	    	  	   ."method (".$v_header['compression'].") ");
3472
3473
              return PclZip::errorCode();
3474
		  }
3475
	  }
3476
3477
	  // ----- Check encrypted files
3478
	  if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3479
          $v_header['status'] = 'unsupported_encryption';
3480
3481
          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3482
          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3483
		      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3484
3485
              $this->privSwapBackMagicQuotes();
3486
3487
              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3488
			                       "Unsupported encryption for "
3489
				  	    	  	   ." filename '".$v_header['stored_filename']
3490
								   ."'");
3491
3492
              return PclZip::errorCode();
3493
		  }
3494
    }
3495
3496
      // ----- Look for real extraction
3497
      if (($v_extract) && ($v_header['status'] != 'ok')) {
3498
          $v_result = $this->privConvertHeader2FileInfo($v_header,
3499
		                                        $p_file_list[$v_nb_extracted++]);
3500
          if ($v_result != 1) {
3501
              $this->privCloseFd();
3502
              $this->privSwapBackMagicQuotes();
3503
              return $v_result;
3504
          }
3505
3506
          $v_extract = false;
3507
      }
3508
3509
      // ----- Look for real extraction
3510
      if ($v_extract)
3511
      {
3512
3513
        // ----- Go to the file position
3514
        @rewind($this->zip_fd);
3515 View Code Duplication
        if (@fseek($this->zip_fd, $v_header['offset']))
3516
        {
3517
          // ----- Close the zip file
3518
          $this->privCloseFd();
3519
3520
          $this->privSwapBackMagicQuotes();
3521
3522
          // ----- Error log
3523
          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3524
3525
          // ----- Return
3526
          return PclZip::errorCode();
3527
        }
3528
3529
        // ----- Look for extraction as string
3530
        if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3531
3532
          $v_string = '';
3533
3534
          // ----- Extracting the file
3535
          $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3536
          if ($v_result1 < 1) {
3537
            $this->privCloseFd();
3538
            $this->privSwapBackMagicQuotes();
3539
            return $v_result1;
3540
          }
3541
3542
          // ----- Get the only interesting attributes
3543 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3544
          {
3545
            // ----- Close the zip file
3546
            $this->privCloseFd();
3547
            $this->privSwapBackMagicQuotes();
3548
3549
            return $v_result;
3550
          }
3551
3552
          // ----- Set the file content
3553
          $p_file_list[$v_nb_extracted]['content'] = $v_string;
3554
3555
          // ----- Next extracted file
3556
          $v_nb_extracted++;
3557
3558
          // ----- Look for user callback abort
3559
          if ($v_result1 == 2) {
3560
          	break;
3561
          }
3562
        }
3563
        // ----- Look for extraction in standard output
3564
        elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3565
		        && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3566
          // ----- Extracting the file in standard output
3567
          $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3568
          if ($v_result1 < 1) {
3569
            $this->privCloseFd();
3570
            $this->privSwapBackMagicQuotes();
3571
            return $v_result1;
3572
          }
3573
3574
          // ----- Get the only interesting attributes
3575 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3576
            $this->privCloseFd();
3577
            $this->privSwapBackMagicQuotes();
3578
            return $v_result;
3579
          }
3580
3581
          // ----- Look for user callback abort
3582
          if ($v_result1 == 2) {
3583
          	break;
3584
          }
3585
        }
3586
        // ----- Look for normal extraction
3587
        else {
3588
          // ----- Extracting the file
3589
          $v_result1 = $this->privExtractFile($v_header,
3590
		                                      $p_path, $p_remove_path,
3591
											  $p_remove_all_path,
3592
											  $p_options);
3593
          if ($v_result1 < 1) {
3594
            $this->privCloseFd();
3595
            $this->privSwapBackMagicQuotes();
3596
            return $v_result1;
3597
          }
3598
3599
          // ----- Get the only interesting attributes
3600 View Code Duplication
          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3601
          {
3602
            // ----- Close the zip file
3603
            $this->privCloseFd();
3604
            $this->privSwapBackMagicQuotes();
3605
3606
            return $v_result;
3607
          }
3608
3609
          // ----- Look for user callback abort
3610
          if ($v_result1 == 2) {
3611
          	break;
3612
          }
3613
        }
3614
      }
3615
    }
3616
3617
    // ----- Close the zip file
3618
    $this->privCloseFd();
3619
    $this->privSwapBackMagicQuotes();
3620
3621
    // ----- Return
3622
    return $v_result;
3623
  }
3624
  // --------------------------------------------------------------------------------
3625
3626
  // --------------------------------------------------------------------------------
3627
  // Function : privExtractFile()
3628
  // Description :
3629
  // Parameters :
3630
  // Return Values :
3631
  //
3632
  // 1 : ... ?
3633
  // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3634
  // --------------------------------------------------------------------------------
3635
  function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3636
  {
3637
    $v_result=1;
3638
3639
    // ----- Read the file header
3640
    if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3641
    {
3642
      // ----- Return
3643
      return $v_result;
3644
    }
3645
3646
3647
    // ----- Check that the file header is coherent with $p_entry info
3648
    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...
3649
        // TBC
3650
    }
3651
3652
    // ----- Look for all path to remove
3653
    if ($p_remove_all_path == true) {
3654
        // ----- Look for folder entry that not need to be extracted
3655
        if (($p_entry['external']&0x00000010)==0x00000010) {
3656
3657
            $p_entry['status'] = "filtered";
3658
3659
            return $v_result;
3660
        }
3661
3662
        // ----- Get the basename of the path
3663
        $p_entry['filename'] = basename($p_entry['filename']);
3664
    }
3665
3666
    // ----- Look for path to remove
3667
    else if ($p_remove_path != "")
3668
    {
3669
      if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3670
      {
3671
3672
        // ----- Change the file status
3673
        $p_entry['status'] = "filtered";
3674
3675
        // ----- Return
3676
        return $v_result;
3677
      }
3678
3679
      $p_remove_path_size = strlen($p_remove_path);
3680
      if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3681
      {
3682
3683
        // ----- Remove the path
3684
        $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3685
3686
      }
3687
    }
3688
3689
    // ----- Add the path
3690
    if ($p_path != '') {
3691
      $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3692
    }
3693
3694
    // ----- Check a base_dir_restriction
3695
    if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3696
      $v_inclusion
3697
      = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3698
                                $p_entry['filename']);
3699 View Code Duplication
      if ($v_inclusion == 0) {
3700
3701
        PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3702
			                     "Filename '".$p_entry['filename']."' is "
3703
								 ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3704
3705
        return PclZip::errorCode();
3706
      }
3707
    }
3708
3709
    // ----- Look for pre-extract callback
3710 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3711
3712
      // ----- Generate a local information
3713
      $v_local_header = array();
3714
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3715
3716
      // ----- Call the callback
3717
      // Here I do not use call_user_func() because I need to send a reference to the
3718
      // header.
3719
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3720
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3721
      if ($v_result == 0) {
3722
        // ----- Change the file status
3723
        $p_entry['status'] = "skipped";
3724
        $v_result = 1;
3725
      }
3726
3727
      // ----- Look for abort result
3728
      if ($v_result == 2) {
3729
        // ----- This status is internal and will be changed in 'skipped'
3730
        $p_entry['status'] = "aborted";
3731
      	$v_result = PCLZIP_ERR_USER_ABORTED;
3732
      }
3733
3734
      // ----- Update the informations
3735
      // Only some fields can be modified
3736
      $p_entry['filename'] = $v_local_header['filename'];
3737
    }
3738
3739
3740
    // ----- Look if extraction should be done
3741
    if ($p_entry['status'] == 'ok') {
3742
3743
    // ----- Look for specific actions while the file exist
3744
    if (file_exists($p_entry['filename']))
3745
    {
3746
3747
      // ----- Look if file is a directory
3748
      if (is_dir($p_entry['filename']))
3749
      {
3750
3751
        // ----- Change the file status
3752
        $p_entry['status'] = "already_a_directory";
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_ALREADY_A_DIRECTORY,
3761
			                     "Filename '".$p_entry['filename']."' is "
3762
								 ."already used by an existing directory");
3763
3764
            return PclZip::errorCode();
3765
		    }
3766
      }
3767
      // ----- Look if file is write protected
3768
      else if (!is_writeable($p_entry['filename']))
3769
      {
3770
3771
        // ----- Change the file status
3772
        $p_entry['status'] = "write_protected";
3773
3774
        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3775
        // For historical reason first PclZip implementation does not stop
3776
        // when this kind of error occurs.
3777 View Code Duplication
        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3778
		    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3779
3780
            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3781
			                     "Filename '".$p_entry['filename']."' exists "
3782
								 ."and is write protected");
3783
3784
            return PclZip::errorCode();
3785
		    }
3786
      }
3787
3788
      // ----- Look if the extracted file is older
3789
      else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3790
      {
3791
        // ----- Change the file status
3792
        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...
3793
		    && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3794
	  	  }
3795 View Code Duplication
		    else {
3796
            $p_entry['status'] = "newer_exist";
3797
3798
            // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3799
            // For historical reason first PclZip implementation does not stop
3800
            // when this kind of error occurs.
3801
            if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3802
		        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3803
3804
                PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3805
			             "Newer version of '".$p_entry['filename']."' exists "
3806
					    ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3807
3808
                return PclZip::errorCode();
3809
		      }
3810
		    }
3811
      }
3812
      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...
3813
      }
3814
    }
3815
3816
    // ----- Check the directory availability and create it if necessary
3817
    else {
3818
      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3819
        $v_dir_to_check = $p_entry['filename'];
3820
      else if (!strstr($p_entry['filename'], "/"))
3821
        $v_dir_to_check = "";
3822
      else
3823
        $v_dir_to_check = dirname($p_entry['filename']);
3824
3825
        if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3826
3827
          // ----- Change the file status
3828
          $p_entry['status'] = "path_creation_fail";
3829
3830
          // ----- Return
3831
          //return $v_result;
3832
          $v_result = 1;
3833
        }
3834
      }
3835
    }
3836
3837
    // ----- Look if extraction should be done
3838
    if ($p_entry['status'] == 'ok') {
3839
3840
      // ----- Do the extraction (if not a folder)
3841
      if (!(($p_entry['external']&0x00000010)==0x00000010))
3842
      {
3843
        // ----- Look for not compressed file
3844
        if ($p_entry['compression'] == 0) {
3845
3846
    		  // ----- Opening destination file
3847 View Code Duplication
          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3848
          {
3849
3850
            // ----- Change the file status
3851
            $p_entry['status'] = "write_error";
3852
3853
            // ----- Return
3854
            return $v_result;
3855
          }
3856
3857
3858
          // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3859
          $v_size = $p_entry['compressed_size'];
3860 View Code Duplication
          while ($v_size != 0)
3861
          {
3862
            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3863
            $v_buffer = @fread($this->zip_fd, $v_read_size);
3864
            /* Try to speed up the code
3865
            $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3866
            @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3867
            */
3868
            @fwrite($v_dest_file, $v_buffer, $v_read_size);
3869
            $v_size -= $v_read_size;
3870
          }
3871
3872
          // ----- Closing the destination file
3873
          fclose($v_dest_file);
3874
3875
          // ----- Change the file mtime
3876
          touch($p_entry['filename'], $p_entry['mtime']);
3877
3878
3879
        }
3880
        else {
3881
          // ----- TBC
3882
          // Need to be finished
3883 View Code Duplication
          if (($p_entry['flag'] & 1) == 1) {
3884
            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
3885
            return PclZip::errorCode();
3886
          }
3887
3888
3889
          // ----- Look for using temporary file to unzip
3890
          if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
3891
              && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
3892
                  || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
3893
                      && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
3894
            $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3895
            if ($v_result < PCLZIP_ERR_NO_ERROR) {
3896
              return $v_result;
3897
            }
3898
          }
3899
3900
          // ----- Look for extract in memory
3901
          else {
3902
3903
3904
            // ----- Read the compressed file in a buffer (one shot)
3905
            $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3906
3907
            // ----- Decompress the file
3908
            $v_file_content = @gzinflate($v_buffer);
3909
            unset($v_buffer);
3910
            if ($v_file_content === FALSE) {
3911
3912
              // ----- Change the file status
3913
              // TBC
3914
              $p_entry['status'] = "error";
3915
3916
              return $v_result;
3917
            }
3918
3919
            // ----- Opening destination file
3920 View Code Duplication
            if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3921
3922
              // ----- Change the file status
3923
              $p_entry['status'] = "write_error";
3924
3925
              return $v_result;
3926
            }
3927
3928
            // ----- Write the uncompressed data
3929
            @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3930
            unset($v_file_content);
3931
3932
            // ----- Closing the destination file
3933
            @fclose($v_dest_file);
3934
3935
          }
3936
3937
          // ----- Change the file mtime
3938
          @touch($p_entry['filename'], $p_entry['mtime']);
3939
        }
3940
3941
        // ----- Look for chmod option
3942
        if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3943
3944
          // ----- Change the mode of the file
3945
          @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
3946
        }
3947
3948
      }
3949
    }
3950
3951
  	// ----- Change abort status
3952 View Code Duplication
  	if ($p_entry['status'] == "aborted") {
3953
        $p_entry['status'] = "skipped";
3954
  	}
3955
3956
    // ----- Look for post-extract callback
3957
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3958
3959
      // ----- Generate a local information
3960
      $v_local_header = array();
3961
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3962
3963
      // ----- Call the callback
3964
      // Here I do not use call_user_func() because I need to send a reference to the
3965
      // header.
3966
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3967
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3968
3969
      // ----- Look for abort result
3970
      if ($v_result == 2) {
3971
      	$v_result = PCLZIP_ERR_USER_ABORTED;
3972
      }
3973
    }
3974
3975
    // ----- Return
3976
    return $v_result;
3977
  }
3978
  // --------------------------------------------------------------------------------
3979
3980
  // --------------------------------------------------------------------------------
3981
  // Function : privExtractFileUsingTempFile()
3982
  // Description :
3983
  // Parameters :
3984
  // Return Values :
3985
  // --------------------------------------------------------------------------------
3986
  function privExtractFileUsingTempFile(&$p_entry, &$p_options)
3987
  {
3988
    $v_result=1;
3989
3990
    // ----- Creates a temporary file
3991
    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
3992 View Code Duplication
    if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3993
      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...
3994
      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
3995
      return PclZip::errorCode();
3996
    }
3997
3998
3999
    // ----- Write gz file format header
4000
    $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
4001
    @fwrite($v_dest_file, $v_binary_data, 10);
4002
4003
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4004
    $v_size = $p_entry['compressed_size'];
4005 View Code Duplication
    while ($v_size != 0)
4006
    {
4007
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4008
      $v_buffer = @fread($this->zip_fd, $v_read_size);
4009
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4010
      @fwrite($v_dest_file, $v_buffer, $v_read_size);
4011
      $v_size -= $v_read_size;
4012
    }
4013
4014
    // ----- Write gz file format footer
4015
    $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
4016
    @fwrite($v_dest_file, $v_binary_data, 8);
4017
4018
    // ----- Close the temporary file
4019
    @fclose($v_dest_file);
4020
4021
    // ----- Opening destination file
4022 View Code Duplication
    if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
4023
      $p_entry['status'] = "write_error";
4024
      return $v_result;
4025
    }
4026
4027
    // ----- Open the temporary gz file
4028 View Code Duplication
    if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
4029
      @fclose($v_dest_file);
4030
      $p_entry['status'] = "read_error";
4031
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
4032
      return PclZip::errorCode();
4033
    }
4034
4035
4036
    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4037
    $v_size = $p_entry['size'];
4038 View Code Duplication
    while ($v_size != 0) {
4039
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4040
      $v_buffer = @gzread($v_src_file, $v_read_size);
4041
      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4042
      @fwrite($v_dest_file, $v_buffer, $v_read_size);
4043
      $v_size -= $v_read_size;
4044
    }
4045
    @fclose($v_dest_file);
4046
    @gzclose($v_src_file);
4047
4048
    // ----- Delete the temporary file
4049
    @unlink($v_gzip_temp_name);
4050
4051
    // ----- Return
4052
    return $v_result;
4053
  }
4054
  // --------------------------------------------------------------------------------
4055
4056
  // --------------------------------------------------------------------------------
4057
  // Function : privExtractFileInOutput()
4058
  // Description :
4059
  // Parameters :
4060
  // Return Values :
4061
  // --------------------------------------------------------------------------------
4062
  function privExtractFileInOutput(&$p_entry, &$p_options)
4063
  {
4064
    $v_result=1;
4065
4066
    // ----- Read the file header
4067
    if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
4068
      return $v_result;
4069
    }
4070
4071
4072
    // ----- Check that the file header is coherent with $p_entry info
4073
    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...
4074
        // TBC
4075
    }
4076
4077
    // ----- Look for pre-extract callback
4078 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4079
4080
      // ----- Generate a local information
4081
      $v_local_header = array();
4082
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4083
4084
      // ----- Call the callback
4085
      // Here I do not use call_user_func() because I need to send a reference to the
4086
      // header.
4087
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4088
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4089
      if ($v_result == 0) {
4090
        // ----- Change the file status
4091
        $p_entry['status'] = "skipped";
4092
        $v_result = 1;
4093
      }
4094
4095
      // ----- Look for abort result
4096
      if ($v_result == 2) {
4097
        // ----- This status is internal and will be changed in 'skipped'
4098
        $p_entry['status'] = "aborted";
4099
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4100
      }
4101
4102
      // ----- Update the informations
4103
      // Only some fields can be modified
4104
      $p_entry['filename'] = $v_local_header['filename'];
4105
    }
4106
4107
    // ----- Trace
4108
4109
    // ----- Look if extraction should be done
4110
    if ($p_entry['status'] == 'ok') {
4111
4112
      // ----- Do the extraction (if not a folder)
4113
      if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4114
        // ----- Look for not compressed file
4115
        if ($p_entry['compressed_size'] == $p_entry['size']) {
4116
4117
          // ----- Read the file in a buffer (one shot)
4118
          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4119
4120
          // ----- Send the file to the output
4121
          echo $v_buffer;
4122
          unset($v_buffer);
4123
        }
4124
        else {
4125
4126
          // ----- Read the compressed file in a buffer (one shot)
4127
          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4128
4129
          // ----- Decompress the file
4130
          $v_file_content = gzinflate($v_buffer);
4131
          unset($v_buffer);
4132
4133
          // ----- Send the file to the output
4134
          echo $v_file_content;
4135
          unset($v_file_content);
4136
        }
4137
      }
4138
    }
4139
4140
	// ----- Change abort status
4141 View Code Duplication
	if ($p_entry['status'] == "aborted") {
4142
      $p_entry['status'] = "skipped";
4143
	}
4144
4145
    // ----- Look for post-extract callback
4146
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4147
4148
      // ----- Generate a local information
4149
      $v_local_header = array();
4150
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4151
4152
      // ----- Call the callback
4153
      // Here I do not use call_user_func() because I need to send a reference to the
4154
      // header.
4155
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4156
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4157
4158
      // ----- Look for abort result
4159
      if ($v_result == 2) {
4160
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4161
      }
4162
    }
4163
4164
    return $v_result;
4165
  }
4166
  // --------------------------------------------------------------------------------
4167
4168
  // --------------------------------------------------------------------------------
4169
  // Function : privExtractFileAsString()
4170
  // Description :
4171
  // Parameters :
4172
  // Return Values :
4173
  // --------------------------------------------------------------------------------
4174
  function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
4175
  {
4176
    $v_result=1;
4177
4178
    // ----- Read the file header
4179
    $v_header = array();
4180
    if (($v_result = $this->privReadFileHeader($v_header)) != 1)
4181
    {
4182
      // ----- Return
4183
      return $v_result;
4184
    }
4185
4186
4187
    // ----- Check that the file header is coherent with $p_entry info
4188
    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...
4189
        // TBC
4190
    }
4191
4192
    // ----- Look for pre-extract callback
4193 View Code Duplication
    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4194
4195
      // ----- Generate a local information
4196
      $v_local_header = array();
4197
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4198
4199
      // ----- Call the callback
4200
      // Here I do not use call_user_func() because I need to send a reference to the
4201
      // header.
4202
//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4203
      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4204
      if ($v_result == 0) {
4205
        // ----- Change the file status
4206
        $p_entry['status'] = "skipped";
4207
        $v_result = 1;
4208
      }
4209
4210
      // ----- Look for abort result
4211
      if ($v_result == 2) {
4212
        // ----- This status is internal and will be changed in 'skipped'
4213
        $p_entry['status'] = "aborted";
4214
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4215
      }
4216
4217
      // ----- Update the informations
4218
      // Only some fields can be modified
4219
      $p_entry['filename'] = $v_local_header['filename'];
4220
    }
4221
4222
4223
    // ----- Look if extraction should be done
4224
    if ($p_entry['status'] == 'ok') {
4225
4226
      // ----- Do the extraction (if not a folder)
4227
      if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4228
        // ----- Look for not compressed file
4229
  //      if ($p_entry['compressed_size'] == $p_entry['size'])
4230
        if ($p_entry['compression'] == 0) {
4231
4232
          // ----- Reading the file
4233
          $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4234
        }
4235
        else {
4236
4237
          // ----- Reading the file
4238
          $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4239
4240
          // ----- Decompress the file
4241
          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...
4242
              // TBC
4243
          }
4244
        }
4245
4246
        // ----- Trace
4247
      }
4248
      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...
4249
          // TBC : error : can not extract a folder in a string
4250
      }
4251
4252
    }
4253
4254
  	// ----- Change abort status
4255 View Code Duplication
  	if ($p_entry['status'] == "aborted") {
4256
        $p_entry['status'] = "skipped";
4257
  	}
4258
4259
    // ----- Look for post-extract callback
4260
    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4261
4262
      // ----- Generate a local information
4263
      $v_local_header = array();
4264
      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4265
4266
      // ----- Swap the content to header
4267
      $v_local_header['content'] = $p_string;
4268
      $p_string = '';
4269
4270
      // ----- Call the callback
4271
      // Here I do not use call_user_func() because I need to send a reference to the
4272
      // header.
4273
//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4274
      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4275
4276
      // ----- Swap back the content to header
4277
      $p_string = $v_local_header['content'];
4278
      unset($v_local_header['content']);
4279
4280
      // ----- Look for abort result
4281
      if ($v_result == 2) {
4282
      	$v_result = PCLZIP_ERR_USER_ABORTED;
4283
      }
4284
    }
4285
4286
    // ----- Return
4287
    return $v_result;
4288
  }
4289
  // --------------------------------------------------------------------------------
4290
4291
  // --------------------------------------------------------------------------------
4292
  // Function : privReadFileHeader()
4293
  // Description :
4294
  // Parameters :
4295
  // Return Values :
4296
  // --------------------------------------------------------------------------------
4297
  function privReadFileHeader(&$p_header)
4298
  {
4299
    $v_result=1;
4300
4301
    // ----- Read the 4 bytes signature
4302
    $v_binary_data = @fread($this->zip_fd, 4);
4303
    $v_data = unpack('Vid', $v_binary_data);
4304
4305
    // ----- Check signature
4306
    if ($v_data['id'] != 0x04034b50)
4307
    {
4308
4309
      // ----- Error log
4310
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4311
4312
      // ----- Return
4313
      return PclZip::errorCode();
4314
    }
4315
4316
    // ----- Read the first 42 bytes of the header
4317
    $v_binary_data = fread($this->zip_fd, 26);
4318
4319
    // ----- Look for invalid block size
4320 View Code Duplication
    if (strlen($v_binary_data) != 26)
4321
    {
4322
      $p_header['filename'] = "";
4323
      $p_header['status'] = "invalid_header";
4324
4325
      // ----- Error log
4326
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4327
4328
      // ----- Return
4329
      return PclZip::errorCode();
4330
    }
4331
4332
    // ----- Extract the values
4333
    $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4334
4335
    // ----- Get filename
4336
    $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4337
4338
    // ----- Get extra_fields
4339
    if ($v_data['extra_len'] != 0) {
4340
      $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4341
    }
4342
    else {
4343
      $p_header['extra'] = '';
4344
    }
4345
4346
    // ----- Extract properties
4347
    $p_header['version_extracted'] = $v_data['version'];
4348
    $p_header['compression'] = $v_data['compression'];
4349
    $p_header['size'] = $v_data['size'];
4350
    $p_header['compressed_size'] = $v_data['compressed_size'];
4351
    $p_header['crc'] = $v_data['crc'];
4352
    $p_header['flag'] = $v_data['flag'];
4353
    $p_header['filename_len'] = $v_data['filename_len'];
4354
4355
    // ----- Recuperate date in UNIX format
4356
    $p_header['mdate'] = $v_data['mdate'];
4357
    $p_header['mtime'] = $v_data['mtime'];
4358
    if ($p_header['mdate'] && $p_header['mtime'])
4359
    {
4360
      // ----- Extract time
4361
      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4362
      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4363
      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4364
4365
      // ----- Extract date
4366
      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4367
      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4368
      $v_day = $p_header['mdate'] & 0x001F;
4369
4370
      // ----- Get UNIX date format
4371
      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4372
4373
    }
4374
    else
4375
    {
4376
      $p_header['mtime'] = time();
4377
    }
4378
4379
    // TBC
4380
    //for(reset($v_data); $key = key($v_data); next($v_data)) {
4381
    //}
4382
4383
    // ----- Set the stored filename
4384
    $p_header['stored_filename'] = $p_header['filename'];
4385
4386
    // ----- Set the status field
4387
    $p_header['status'] = "ok";
4388
4389
    // ----- Return
4390
    return $v_result;
4391
  }
4392
  // --------------------------------------------------------------------------------
4393
4394
  // --------------------------------------------------------------------------------
4395
  // Function : privReadCentralFileHeader()
4396
  // Description :
4397
  // Parameters :
4398
  // Return Values :
4399
  // --------------------------------------------------------------------------------
4400
  function privReadCentralFileHeader(&$p_header)
4401
  {
4402
    $v_result=1;
4403
4404
    // ----- Read the 4 bytes signature
4405
    $v_binary_data = @fread($this->zip_fd, 4);
4406
    $v_data = unpack('Vid', $v_binary_data);
4407
4408
    // ----- Check signature
4409
    if ($v_data['id'] != 0x02014b50)
4410
    {
4411
4412
      // ----- Error log
4413
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4414
4415
      // ----- Return
4416
      return PclZip::errorCode();
4417
    }
4418
4419
    // ----- Read the first 42 bytes of the header
4420
    $v_binary_data = fread($this->zip_fd, 42);
4421
4422
    // ----- Look for invalid block size
4423 View Code Duplication
    if (strlen($v_binary_data) != 42)
4424
    {
4425
      $p_header['filename'] = "";
4426
      $p_header['status'] = "invalid_header";
4427
4428
      // ----- Error log
4429
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4430
4431
      // ----- Return
4432
      return PclZip::errorCode();
4433
    }
4434
4435
    // ----- Extract the values
4436
    $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);
4437
4438
    // ----- Get filename
4439
    if ($p_header['filename_len'] != 0)
4440
      //
4441
      // --------------------------------------------------------------------------------
4442
      // A patch about stored filenames with backslash directory separator (Windows style).
4443
      // Archives created by the utility IZArc 3.81 (possibly new versions too) need this patch.
4444
      //$p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4445
      $p_header['filename'] = str_replace("\\", '/', fread($this->zip_fd, $p_header['filename_len']));
4446
      // --------------------------------------------------------------------------------
4447
      //
4448
    else
4449
      $p_header['filename'] = '';
4450
4451
    // ----- Get extra
4452 View Code Duplication
    if ($p_header['extra_len'] != 0)
4453
      $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4454
    else
4455
      $p_header['extra'] = '';
4456
4457
    // ----- Get comment
4458 View Code Duplication
    if ($p_header['comment_len'] != 0)
4459
      $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4460
    else
4461
      $p_header['comment'] = '';
4462
4463
    // ----- Extract properties
4464
4465
    // ----- Recuperate date in UNIX format
4466
    //if ($p_header['mdate'] && $p_header['mtime'])
4467
    // TBC : bug : this was ignoring time with 0/0/0
4468
    if (1)
4469
    {
4470
      // ----- Extract time
4471
      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4472
      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4473
      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4474
4475
      // ----- Extract date
4476
      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4477
      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4478
      $v_day = $p_header['mdate'] & 0x001F;
4479
4480
      // ----- Get UNIX date format
4481
      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4482
4483
    }
4484
    else
4485
    {
4486
      $p_header['mtime'] = time();
4487
    }
4488
4489
    // ----- Set the stored filename
4490
    $p_header['stored_filename'] = $p_header['filename'];
4491
4492
    // ----- Set default status to ok
4493
    $p_header['status'] = 'ok';
4494
4495
    // ----- Look if it is a directory
4496
    if (substr($p_header['filename'], -1) == '/') {
4497
      //$p_header['external'] = 0x41FF0010;
4498
      $p_header['external'] = 0x00000010;
4499
    }
4500
4501
4502
    // ----- Return
4503
    return $v_result;
4504
  }
4505
  // --------------------------------------------------------------------------------
4506
4507
  // --------------------------------------------------------------------------------
4508
  // Function : privCheckFileHeaders()
4509
  // Description :
4510
  // Parameters :
4511
  // Return Values :
4512
  //   1 on success,
4513
  //   0 on error;
4514
  // --------------------------------------------------------------------------------
4515
  function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4516
  {
4517
    $v_result=1;
4518
4519
  	// ----- Check the static values
4520
  	// TBC
4521
  	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...
4522
  	}
4523
  	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...
4524
  	}
4525
  	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...
4526
  	}
4527
  	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...
4528
  	}
4529
  	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...
4530
  	}
4531
  	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...
4532
  	}
4533
4534
  	// ----- Look for flag bit 3
4535
  	if (($p_local_header['flag'] & 8) == 8) {
4536
          $p_local_header['size'] = $p_central_header['size'];
4537
          $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4538
          $p_local_header['crc'] = $p_central_header['crc'];
4539
  	}
4540
4541
    // ----- Return
4542
    return $v_result;
4543
  }
4544
  // --------------------------------------------------------------------------------
4545
4546
  // --------------------------------------------------------------------------------
4547
  // Function : privReadEndCentralDir()
4548
  // Description :
4549
  // Parameters :
4550
  // Return Values :
4551
  // --------------------------------------------------------------------------------
4552
  function privReadEndCentralDir(&$p_central_dir)
4553
  {
4554
    $v_result=1;
4555
4556
    // ----- Go to the end of the zip file
4557
    $v_size = filesize($this->zipname);
4558
    @fseek($this->zip_fd, $v_size);
4559 View Code Duplication
    if (@ftell($this->zip_fd) != $v_size)
4560
    {
4561
      // ----- Error log
4562
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4563
4564
      // ----- Return
4565
      return PclZip::errorCode();
4566
    }
4567
4568
    // ----- First try : look if this is an archive with no commentaries (most of the time)
4569
    // in this case the end of central dir is at 22 bytes of the file end
4570
    $v_found = 0;
4571
    if ($v_size > 26) {
4572
      @fseek($this->zip_fd, $v_size-22);
4573 View Code Duplication
      if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
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 for bytes
4583
      $v_binary_data = @fread($this->zip_fd, 4);
4584
      $v_data = @unpack('Vid', $v_binary_data);
4585
4586
      // ----- Check signature
4587
      if ($v_data['id'] == 0x06054b50) {
4588
        $v_found = 1;
4589
      }
4590
4591
      $v_pos = ftell($this->zip_fd);
4592
    }
4593
4594
    // ----- Go back to the maximum possible size of the Central Dir End Record
4595
    if (!$v_found) {
4596
      $v_maximum_size = 65557; // 0xFFFF + 22;
4597
      if ($v_maximum_size > $v_size)
4598
        $v_maximum_size = $v_size;
4599
      @fseek($this->zip_fd, $v_size-$v_maximum_size);
4600 View Code Duplication
      if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4601
      {
4602
        // ----- Error log
4603
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4604
4605
        // ----- Return
4606
        return PclZip::errorCode();
4607
      }
4608
4609
      // ----- Read byte per byte in order to find the signature
4610
      $v_pos = ftell($this->zip_fd);
4611
      $v_bytes = 0x00000000;
4612
      while ($v_pos < $v_size)
4613
      {
4614
        // ----- Read a byte
4615
        $v_byte = @fread($this->zip_fd, 1);
4616
4617
        // -----  Add the byte
4618
        //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
4619
        // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
4620
        // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
4621
        $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
4622
4623
        // ----- Compare the bytes
4624
        if ($v_bytes == 0x504b0506)
4625
        {
4626
          $v_pos++;
4627
          break;
4628
        }
4629
4630
        $v_pos++;
4631
      }
4632
4633
      // ----- Look if not found end of central dir
4634
      if ($v_pos == $v_size)
4635
      {
4636
4637
        // ----- Error log
4638
        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4639
4640
        // ----- Return
4641
        return PclZip::errorCode();
4642
      }
4643
    }
4644
4645
    // ----- Read the first 18 bytes of the header
4646
    $v_binary_data = fread($this->zip_fd, 18);
4647
4648
    // ----- Look for invalid block size
4649 View Code Duplication
    if (strlen($v_binary_data) != 18)
4650
    {
4651
4652
      // ----- Error log
4653
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4654
4655
      // ----- Return
4656
      return PclZip::errorCode();
4657
    }
4658
4659
    // ----- Extract the values
4660
    $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4661
4662
    // ----- Check the global size
4663
    if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
4664
4665
	  // ----- Removed in release 2.2 see readme file
4666
	  // The check of the file size is a little too strict.
4667
	  // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4668
	  // While decrypted, zip has training 0 bytes
4669
	  if (0) {
4670
      // ----- Error log
4671
      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4672
	                       'The central dir is not at the end of the archive.'
4673
						   .' Some trailing bytes exists after the archive.');
4674
4675
      // ----- Return
4676
      return PclZip::errorCode();
4677
	  }
4678
    }
4679
4680
    // ----- Get comment
4681
    if ($v_data['comment_size'] != 0) {
4682
      $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4683
    }
4684
    else
4685
      $p_central_dir['comment'] = '';
4686
4687
    $p_central_dir['entries'] = $v_data['entries'];
4688
    $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4689
    $p_central_dir['offset'] = $v_data['offset'];
4690
    $p_central_dir['size'] = $v_data['size'];
4691
    $p_central_dir['disk'] = $v_data['disk'];
4692
    $p_central_dir['disk_start'] = $v_data['disk_start'];
4693
4694
    // TBC
4695
    //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4696
    //}
4697
4698
    // ----- Return
4699
    return $v_result;
4700
  }
4701
  // --------------------------------------------------------------------------------
4702
4703
  // --------------------------------------------------------------------------------
4704
  // Function : privDeleteByRule()
4705
  // Description :
4706
  // Parameters :
4707
  // Return Values :
4708
  // --------------------------------------------------------------------------------
4709
  function privDeleteByRule(&$p_result_list, &$p_options)
4710
  {
4711
    $v_result=1;
4712
    $v_list_detail = array();
4713
4714
    // ----- Open the zip file
4715
    if (($v_result=$this->privOpenFd('rb')) != 1)
4716
    {
4717
      // ----- Return
4718
      return $v_result;
4719
    }
4720
4721
    // ----- Read the central directory informations
4722
    $v_central_dir = array();
4723
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4724
    {
4725
      $this->privCloseFd();
4726
      return $v_result;
4727
    }
4728
4729
    // ----- Go to beginning of File
4730
    @rewind($this->zip_fd);
4731
4732
    // ----- Scan all the files
4733
    // ----- Start at beginning of Central Dir
4734
    $v_pos_entry = $v_central_dir['offset'];
4735
    @rewind($this->zip_fd);
4736 View Code Duplication
    if (@fseek($this->zip_fd, $v_pos_entry))
4737
    {
4738
      // ----- Close the zip file
4739
      $this->privCloseFd();
4740
4741
      // ----- Error log
4742
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4743
4744
      // ----- Return
4745
      return PclZip::errorCode();
4746
    }
4747
4748
    // ----- Read each entry
4749
    $v_header_list = array();
4750
    $j_start = 0;
4751
    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4752
    {
4753
4754
      // ----- Read the file header
4755
      $v_header_list[$v_nb_extracted] = array();
4756
      if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4757
      {
4758
        // ----- Close the zip file
4759
        $this->privCloseFd();
4760
4761
        return $v_result;
4762
      }
4763
4764
4765
      // ----- Store the index
4766
      $v_header_list[$v_nb_extracted]['index'] = $i;
4767
4768
      // ----- Look for the specific extract rules
4769
      $v_found = false;
4770
4771
      // ----- Look for extract by name rule
4772
      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
4773
          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4774
4775
          // ----- Look if the filename is in the list
4776
          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4777
4778
              // ----- Look for a directory
4779
              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4780
4781
                  // ----- Look if the directory is in the filename path
4782
                  if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4783
                      && (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])) {
4784
                      $v_found = true;
4785
                  }
4786
                  elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4787
                          && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4788
                      $v_found = true;
4789
                  }
4790
              }
4791
              // ----- Look for a filename
4792
              elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4793
                  $v_found = true;
4794
              }
4795
          }
4796
      }
4797
4798
      // ----- Look for extract by ereg rule
4799
      // ereg() is deprecated with PHP 5.3
4800
      /*
4801
      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
4802
               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4803
4804
          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4805
              $v_found = true;
4806
          }
4807
      }
4808
      */
4809
4810
      // ----- Look for extract by preg rule
4811 View Code Duplication
      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
4812
               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4813
4814
          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4815
              $v_found = true;
4816
          }
4817
      }
4818
4819
      // ----- Look for extract by index rule
4820
      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4821
               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4822
4823
          // ----- Look if the index is in the list
4824
          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4825
4826
              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4827
                  $v_found = true;
4828
              }
4829
              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4830
                  $j_start = $j+1;
4831
              }
4832
4833
              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4834
                  break;
4835
              }
4836
          }
4837
      }
4838
      else {
4839
      	$v_found = true;
4840
      }
4841
4842
      // ----- Look for deletion
4843
      if ($v_found)
4844
      {
4845
        unset($v_header_list[$v_nb_extracted]);
4846
      }
4847
      else
4848
      {
4849
        $v_nb_extracted++;
4850
      }
4851
    }
4852
4853
    // ----- Look if something need to be deleted
4854
    if ($v_nb_extracted > 0) {
4855
4856
        // ----- Creates a temporay file
4857
        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4858
4859
        // ----- Creates a temporary zip archive
4860
        $v_temp_zip = new PclZip($v_zip_temp_name);
4861
4862
        // ----- Open the temporary zip file in write mode
4863
        if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4864
            $this->privCloseFd();
4865
4866
            // ----- Return
4867
            return $v_result;
4868
        }
4869
4870
        // ----- Look which file need to be kept
4871
        for ($i=0; $i<sizeof($v_header_list); $i++) {
4872
4873
            // ----- Calculate the position of the header
4874
            @rewind($this->zip_fd);
4875
            if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
4876
                // ----- Close the zip file
4877
                $this->privCloseFd();
4878
                $v_temp_zip->privCloseFd();
4879
                @unlink($v_zip_temp_name);
4880
4881
                // ----- Error log
4882
                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4883
4884
                // ----- Return
4885
                return PclZip::errorCode();
4886
            }
4887
4888
            // ----- Read the file header
4889
            $v_local_header = array();
4890
            if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4891
                // ----- Close the zip file
4892
                $this->privCloseFd();
4893
                $v_temp_zip->privCloseFd();
4894
                @unlink($v_zip_temp_name);
4895
4896
                // ----- Return
4897
                return $v_result;
4898
            }
4899
4900
            // ----- Check that local file header is same as central file header
4901
            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...
4902
			                                $v_header_list[$i]) != 1) {
4903
                // TBC
4904
            }
4905
            unset($v_local_header);
4906
4907
            // ----- Write the file header
4908 View Code Duplication
            if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4909
                // ----- Close the zip file
4910
                $this->privCloseFd();
4911
                $v_temp_zip->privCloseFd();
4912
                @unlink($v_zip_temp_name);
4913
4914
                // ----- Return
4915
                return $v_result;
4916
            }
4917
4918
            // ----- Read/write the data block
4919
            if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4920
                // ----- Close the zip file
4921
                $this->privCloseFd();
4922
                $v_temp_zip->privCloseFd();
4923
                @unlink($v_zip_temp_name);
4924
4925
                // ----- Return
4926
                return $v_result;
4927
            }
4928
        }
4929
4930
        // ----- Store the offset of the central dir
4931
        $v_offset = @ftell($v_temp_zip->zip_fd);
4932
4933
        // ----- Re-Create the Central Dir files header
4934
        for ($i=0; $i<sizeof($v_header_list); $i++) {
4935
            // ----- Create the file header
4936 View Code Duplication
            if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4937
                $v_temp_zip->privCloseFd();
4938
                $this->privCloseFd();
4939
                @unlink($v_zip_temp_name);
4940
4941
                // ----- Return
4942
                return $v_result;
4943
            }
4944
4945
            // ----- Transform the header to a 'usable' info
4946
            $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4947
        }
4948
4949
4950
        // ----- Zip file comment
4951
        $v_comment = '';
4952
        if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4953
          $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4954
        }
4955
4956
        // ----- Calculate the size of the central header
4957
        $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4958
4959
        // ----- Create the central dir footer
4960
        if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4961
            // ----- Reset the file list
4962
            unset($v_header_list);
4963
            $v_temp_zip->privCloseFd();
4964
            $this->privCloseFd();
4965
            @unlink($v_zip_temp_name);
4966
4967
            // ----- Return
4968
            return $v_result;
4969
        }
4970
4971
        // ----- Close
4972
        $v_temp_zip->privCloseFd();
4973
        $this->privCloseFd();
4974
4975
        // ----- Delete the zip file
4976
        // TBC : I should test the result ...
4977
        @unlink($this->zipname);
4978
4979
        // ----- Rename the temporary file
4980
        // TBC : I should test the result ...
4981
        //@rename($v_zip_temp_name, $this->zipname);
4982
        PclZipUtilRename($v_zip_temp_name, $this->zipname);
4983
4984
        // ----- Destroy the temporary archive
4985
        unset($v_temp_zip);
4986
    }
4987
4988
    // ----- Remove every files : reset the file
4989
    else if ($v_central_dir['entries'] != 0) {
4990
        $this->privCloseFd();
4991
4992
        if (($v_result = $this->privOpenFd('wb')) != 1) {
4993
          return $v_result;
4994
        }
4995
4996
        if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4997
          return $v_result;
4998
        }
4999
5000
        $this->privCloseFd();
5001
    }
5002
5003
    // ----- Return
5004
    return $v_result;
5005
  }
5006
  // --------------------------------------------------------------------------------
5007
5008
  // --------------------------------------------------------------------------------
5009
  // Function : privDirCheck()
5010
  // Description :
5011
  //   Check if a directory exists, if not it creates it and all the parents directory
5012
  //   which may be useful.
5013
  // Parameters :
5014
  //   $p_dir : Directory path to check.
5015
  // Return Values :
5016
  //    1 : OK
5017
  //   -1 : Unable to create directory
5018
  // --------------------------------------------------------------------------------
5019
  function privDirCheck($p_dir, $p_is_dir=false)
5020
  {
5021
    $v_result = 1;
5022
5023
5024
    // ----- Remove the final '/'
5025
    if (($p_is_dir) && (substr($p_dir, -1)=='/'))
5026
    {
5027
      $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
5028
    }
5029
5030
    // ----- Check the directory availability
5031
    if ((is_dir($p_dir)) || ($p_dir == ""))
5032
    {
5033
      return 1;
5034
    }
5035
5036
    // ----- Extract parent directory
5037
    $p_parent_dir = dirname($p_dir);
5038
5039
    // ----- Just a check
5040
    if ($p_parent_dir != $p_dir)
5041
    {
5042
      // ----- Look for parent directory
5043
      if ($p_parent_dir != "")
5044
      {
5045
        if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
5046
        {
5047
          return $v_result;
5048
        }
5049
      }
5050
    }
5051
5052
    // ----- Create the directory
5053
    if (!@mkdir($p_dir, 0777))
5054
    {
5055
      // ----- Error log
5056
      PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
5057
5058
      // ----- Return
5059
      return PclZip::errorCode();
5060
    }
5061
5062
    // ----- Return
5063
    return $v_result;
5064
  }
5065
  // --------------------------------------------------------------------------------
5066
5067
  // --------------------------------------------------------------------------------
5068
  // Function : privMerge()
5069
  // Description :
5070
  //   If $p_archive_to_add does not exist, the function exit with a success result.
5071
  // Parameters :
5072
  // Return Values :
5073
  // --------------------------------------------------------------------------------
5074
  function privMerge(&$p_archive_to_add)
5075
  {
5076
    $v_result=1;
5077
5078
    // ----- Look if the archive_to_add exists
5079
    if (!is_file($p_archive_to_add->zipname))
5080
    {
5081
5082
      // ----- Nothing to merge, so merge is a success
5083
      $v_result = 1;
5084
5085
      // ----- Return
5086
      return $v_result;
5087
    }
5088
5089
    // ----- Look if the archive exists
5090
    if (!is_file($this->zipname))
5091
    {
5092
5093
      // ----- Do a duplicate
5094
      $v_result = $this->privDuplicate($p_archive_to_add->zipname);
5095
5096
      // ----- Return
5097
      return $v_result;
5098
    }
5099
5100
    // ----- Open the zip file
5101
    if (($v_result=$this->privOpenFd('rb')) != 1)
5102
    {
5103
      // ----- Return
5104
      return $v_result;
5105
    }
5106
5107
    // ----- Read the central directory informations
5108
    $v_central_dir = array();
5109
    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
5110
    {
5111
      $this->privCloseFd();
5112
      return $v_result;
5113
    }
5114
5115
    // ----- Go to beginning of File
5116
    @rewind($this->zip_fd);
5117
5118
    // ----- Open the archive_to_add file
5119
    if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
5120
    {
5121
      $this->privCloseFd();
5122
5123
      // ----- Return
5124
      return $v_result;
5125
    }
5126
5127
    // ----- Read the central directory informations
5128
    $v_central_dir_to_add = array();
5129
    if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5130
    {
5131
      $this->privCloseFd();
5132
      $p_archive_to_add->privCloseFd();
5133
5134
      return $v_result;
5135
    }
5136
5137
    // ----- Go to beginning of File
5138
    @rewind($p_archive_to_add->zip_fd);
5139
5140
    // ----- Creates a temporay file
5141
    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
5142
5143
    // ----- Open the temporary file in write mode
5144
    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
5145
    {
5146
      $this->privCloseFd();
5147
      $p_archive_to_add->privCloseFd();
5148
5149
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
5150
5151
      // ----- Return
5152
      return PclZip::errorCode();
5153
    }
5154
5155
    // ----- Copy the files from the archive to the temporary file
5156
    // TBC : Here I should better append the file and go back to erase the central dir
5157
    $v_size = $v_central_dir['offset'];
5158
    while ($v_size != 0)
5159
    {
5160
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5161
      $v_buffer = fread($this->zip_fd, $v_read_size);
5162
      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5163
      $v_size -= $v_read_size;
5164
    }
5165
5166
    // ----- Copy the files from the archive_to_add into the temporary file
5167
    $v_size = $v_central_dir_to_add['offset'];
5168
    while ($v_size != 0)
5169
    {
5170
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5171
      $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
5172
      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5173
      $v_size -= $v_read_size;
5174
    }
5175
5176
    // ----- Store the offset of the central dir
5177
    $v_offset = @ftell($v_zip_temp_fd);
5178
5179
    // ----- Copy the block of file headers from the old archive
5180
    $v_size = $v_central_dir['size'];
5181 View Code Duplication
    while ($v_size != 0)
5182
    {
5183
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5184
      $v_buffer = @fread($this->zip_fd, $v_read_size);
5185
      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5186
      $v_size -= $v_read_size;
5187
    }
5188
5189
    // ----- Copy the block of file headers from the archive_to_add
5190
    $v_size = $v_central_dir_to_add['size'];
5191 View Code Duplication
    while ($v_size != 0)
5192
    {
5193
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5194
      $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
5195
      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5196
      $v_size -= $v_read_size;
5197
    }
5198
5199
    // ----- Merge the file comments
5200
    $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
5201
5202
    // ----- Calculate the size of the (new) central header
5203
    $v_size = @ftell($v_zip_temp_fd)-$v_offset;
5204
5205
    // ----- Swap the file descriptor
5206
    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
5207
    // the following methods on the temporary fil and not the real archive fd
5208
    $v_swap = $this->zip_fd;
5209
    $this->zip_fd = $v_zip_temp_fd;
5210
    $v_zip_temp_fd = $v_swap;
5211
5212
    // ----- Create the central dir footer
5213
    if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
5214
    {
5215
      $this->privCloseFd();
5216
      $p_archive_to_add->privCloseFd();
5217
      @fclose($v_zip_temp_fd);
5218
      $this->zip_fd = null;
5219
5220
      // ----- Reset the file list
5221
      unset($v_header_list);
5222
5223
      // ----- Return
5224
      return $v_result;
5225
    }
5226
5227
    // ----- Swap back the file descriptor
5228
    $v_swap = $this->zip_fd;
5229
    $this->zip_fd = $v_zip_temp_fd;
5230
    $v_zip_temp_fd = $v_swap;
5231
5232
    // ----- Close
5233
    $this->privCloseFd();
5234
    $p_archive_to_add->privCloseFd();
5235
5236
    // ----- Close the temporary file
5237
    @fclose($v_zip_temp_fd);
5238
5239
    // ----- Delete the zip file
5240
    // TBC : I should test the result ...
5241
    @unlink($this->zipname);
5242
5243
    // ----- Rename the temporary file
5244
    // TBC : I should test the result ...
5245
    //@rename($v_zip_temp_name, $this->zipname);
5246
    PclZipUtilRename($v_zip_temp_name, $this->zipname);
5247
5248
    // ----- Return
5249
    return $v_result;
5250
  }
5251
  // --------------------------------------------------------------------------------
5252
5253
  // --------------------------------------------------------------------------------
5254
  // Function : privDuplicate()
5255
  // Description :
5256
  // Parameters :
5257
  // Return Values :
5258
  // --------------------------------------------------------------------------------
5259
  function privDuplicate($p_archive_filename)
5260
  {
5261
    $v_result=1;
5262
5263
    // ----- Look if the $p_archive_filename exists
5264
    if (!is_file($p_archive_filename))
5265
    {
5266
5267
      // ----- Nothing to duplicate, so duplicate is a success.
5268
      $v_result = 1;
5269
5270
      // ----- Return
5271
      return $v_result;
5272
    }
5273
5274
    // ----- Open the zip file
5275
    if (($v_result=$this->privOpenFd('wb')) != 1)
5276
    {
5277
      // ----- Return
5278
      return $v_result;
5279
    }
5280
5281
    // ----- Open the temporary file in write mode
5282 View Code Duplication
    if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
5283
    {
5284
      $this->privCloseFd();
5285
5286
      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
5287
5288
      // ----- Return
5289
      return PclZip::errorCode();
5290
    }
5291
5292
    // ----- Copy the files from the archive to the temporary file
5293
    // TBC : Here I should better append the file and go back to erase the central dir
5294
    $v_size = filesize($p_archive_filename);
5295
    while ($v_size != 0)
5296
    {
5297
      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5298
      $v_buffer = fread($v_zip_temp_fd, $v_read_size);
5299
      @fwrite($this->zip_fd, $v_buffer, $v_read_size);
5300
      $v_size -= $v_read_size;
5301
    }
5302
5303
    // ----- Close
5304
    $this->privCloseFd();
5305
5306
    // ----- Close the temporary file
5307
    @fclose($v_zip_temp_fd);
5308
5309
    // ----- Return
5310
    return $v_result;
5311
  }
5312
  // --------------------------------------------------------------------------------
5313
5314
  // --------------------------------------------------------------------------------
5315
  // Function : privErrorLog()
5316
  // Description :
5317
  // Parameters :
5318
  // --------------------------------------------------------------------------------
5319
  function privErrorLog($p_error_code=0, $p_error_string='')
5320
  {
5321
    if (PCLZIP_ERROR_EXTERNAL == 1) {
5322
      PclError($p_error_code, $p_error_string);
5323
    }
5324
    else {
5325
      $this->error_code = $p_error_code;
5326
      $this->error_string = $p_error_string;
5327
    }
5328
  }
5329
  // --------------------------------------------------------------------------------
5330
5331
  // --------------------------------------------------------------------------------
5332
  // Function : privErrorReset()
5333
  // Description :
5334
  // Parameters :
5335
  // --------------------------------------------------------------------------------
5336
  function privErrorReset()
5337
  {
5338
    if (PCLZIP_ERROR_EXTERNAL == 1) {
5339
      PclErrorReset();
5340
    }
5341
    else {
5342
      $this->error_code = 0;
5343
      $this->error_string = '';
5344
    }
5345
  }
5346
  // --------------------------------------------------------------------------------
5347
5348
  // --------------------------------------------------------------------------------
5349
  // Function : privDisableMagicQuotes()
5350
  // Description :
5351
  // Parameters :
5352
  // Return Values :
5353
  // --------------------------------------------------------------------------------
5354 View Code Duplication
  function privDisableMagicQuotes()
5355
  {
5356
    $v_result=1;
5357
5358
    // ----- Look if function exists
5359
    if (   (!function_exists("get_magic_quotes_runtime"))
5360
	    || (!function_exists("set_magic_quotes_runtime"))) {
5361
      return $v_result;
5362
	}
5363
5364
    // ----- Look if already done
5365
    if ($this->magic_quotes_status != -1) {
5366
      return $v_result;
5367
	}
5368
5369
	// ----- Get and memorize the magic_quote value
5370
	$this->magic_quotes_status = @get_magic_quotes_runtime();
5371
5372
	// ----- Disable magic_quotes
5373
	if ($this->magic_quotes_status == 1) {
5374
	  @set_magic_quotes_runtime(0);
5375
	}
5376
5377
    // ----- Return
5378
    return $v_result;
5379
  }
5380
  // --------------------------------------------------------------------------------
5381
5382
  // --------------------------------------------------------------------------------
5383
  // Function : privSwapBackMagicQuotes()
5384
  // Description :
5385
  // Parameters :
5386
  // Return Values :
5387
  // --------------------------------------------------------------------------------
5388 View Code Duplication
  function privSwapBackMagicQuotes()
5389
  {
5390
    $v_result=1;
5391
5392
    // ----- Look if function exists
5393
    if (   (!function_exists("get_magic_quotes_runtime"))
5394
	    || (!function_exists("set_magic_quotes_runtime"))) {
5395
      return $v_result;
5396
	}
5397
5398
    // ----- Look if something to do
5399
    if ($this->magic_quotes_status != -1) {
5400
      return $v_result;
5401
	}
5402
5403
	// ----- Swap back magic_quotes
5404
	if ($this->magic_quotes_status == 1) {
5405
  	  @set_magic_quotes_runtime($this->magic_quotes_status);
5406
	}
5407
5408
    // ----- Return
5409
    return $v_result;
5410
  }
5411
  // --------------------------------------------------------------------------------
5412
5413
  }
5414
  // End of class
5415
  // --------------------------------------------------------------------------------
5416
5417
  // --------------------------------------------------------------------------------
5418
  // Function : PclZipUtilPathReduction()
5419
  // Description :
5420
  // Parameters :
5421
  // Return Values :
5422
  // --------------------------------------------------------------------------------
5423
  function PclZipUtilPathReduction($p_dir)
5424
  {
5425
    $v_result = "";
5426
5427
    // ----- Look for not empty path
5428
    if ($p_dir != "") {
5429
      // ----- Explode path by directory names
5430
      $v_list = explode("/", $p_dir);
5431
5432
      // ----- Study directories from last to first
5433
      $v_skip = 0;
5434
      for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5435
        // ----- Look for current path
5436
        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...
5437
          // ----- Ignore this directory
5438
          // Should be the first $i=0, but no check is done
5439
        }
5440
        else if ($v_list[$i] == "..") {
5441
		  $v_skip++;
5442
        }
5443
        else if ($v_list[$i] == "") {
5444
		  // ----- First '/' i.e. root slash
5445
		  if ($i == 0) {
5446
            $v_result = "/".$v_result;
5447
		    if ($v_skip > 0) {
5448
		        // ----- It is an invalid path, so the path is not modified
5449
		        // TBC
5450
		        $v_result = $p_dir;
5451
                $v_skip = 0;
5452
		    }
5453
		  }
5454
		  // ----- Last '/' i.e. indicates a directory
5455
		  else if ($i == (sizeof($v_list)-1)) {
5456
            $v_result = $v_list[$i];
5457
		  }
5458
		  // ----- Double '/' inside the path
5459
		  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...
5460
            // ----- Ignore only the double '//' in path,
5461
            // but not the first and last '/'
5462
		  }
5463
        }
5464
        else {
5465
		  // ----- Look for item to skip
5466
		  if ($v_skip > 0) {
5467
		    $v_skip--;
5468
		  }
5469
		  else {
5470
            $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5471
		  }
5472
        }
5473
      }
5474
5475
      // ----- Look for skip
5476
      if ($v_skip > 0) {
5477
        while ($v_skip > 0) {
5478
            $v_result = '../'.$v_result;
5479
            $v_skip--;
5480
        }
5481
      }
5482
    }
5483
5484
    // ----- Return
5485
    return $v_result;
5486
  }
5487
  // --------------------------------------------------------------------------------
5488
5489
  // --------------------------------------------------------------------------------
5490
  // Function : PclZipUtilPathInclusion()
5491
  // Description :
5492
  //   This function indicates if the path $p_path is under the $p_dir tree. Or,
5493
  //   said in an other way, if the file or sub-dir $p_path is inside the dir
5494
  //   $p_dir.
5495
  //   The function indicates also if the path is exactly the same as the dir.
5496
  //   This function supports path with duplicated '/' like '//', but does not
5497
  //   support '.' or '..' statements.
5498
  // Parameters :
5499
  // Return Values :
5500
  //   0 if $p_path is not inside directory $p_dir
5501
  //   1 if $p_path is inside directory $p_dir
5502
  //   2 if $p_path is exactly the same as $p_dir
5503
  // --------------------------------------------------------------------------------
5504
  function PclZipUtilPathInclusion($p_dir, $p_path)
5505
  {
5506
    $v_result = 1;
5507
5508
    // ----- Look for path beginning by ./
5509 View Code Duplication
    if (   ($p_dir == '.')
5510
        || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
5511
      $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
5512
    }
5513 View Code Duplication
    if (   ($p_path == '.')
5514
        || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
5515
      $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
5516
    }
5517
5518
    // ----- Explode dir and path by directory separator
5519
    $v_list_dir = explode("/", $p_dir);
5520
    $v_list_dir_size = sizeof($v_list_dir);
5521
    $v_list_path = explode("/", $p_path);
5522
    $v_list_path_size = sizeof($v_list_path);
5523
5524
    // ----- Study directories paths
5525
    $i = 0;
5526
    $j = 0;
5527
    while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5528
5529
      // ----- Look for empty dir (path reduction)
5530
      if ($v_list_dir[$i] == '') {
5531
        $i++;
5532
        continue;
5533
      }
5534
      if ($v_list_path[$j] == '') {
5535
        $j++;
5536
        continue;
5537
      }
5538
5539
      // ----- Compare the items
5540
      if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {
5541
        $v_result = 0;
5542
      }
5543
5544
      // ----- Next items
5545
      $i++;
5546
      $j++;
5547
    }
5548
5549
    // ----- Look if everything seems to be the same
5550
    if ($v_result) {
5551
      // ----- Skip all the empty items
5552
      while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5553
      while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5554
5555
      if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5556
        // ----- There are exactly the same
5557
        $v_result = 2;
5558
      }
5559
      else if ($i < $v_list_dir_size) {
5560
        // ----- The path is shorter than the dir
5561
        $v_result = 0;
5562
      }
5563
    }
5564
5565
    // ----- Return
5566
    return $v_result;
5567
  }
5568
  // --------------------------------------------------------------------------------
5569
5570
  // --------------------------------------------------------------------------------
5571
  // Function : PclZipUtilCopyBlock()
5572
  // Description :
5573
  // Parameters :
5574
  //   $p_mode : read/write compression mode
5575
  //             0 : src & dest normal
5576
  //             1 : src gzip, dest normal
5577
  //             2 : src normal, dest gzip
5578
  //             3 : src & dest gzip
5579
  // Return Values :
5580
  // --------------------------------------------------------------------------------
5581
  function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5582
  {
5583
    $v_result = 1;
5584
5585
    if ($p_mode==0)
5586
    {
5587 View Code Duplication
      while ($p_size != 0)
5588
      {
5589
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5590
        $v_buffer = @fread($p_src, $v_read_size);
5591
        @fwrite($p_dest, $v_buffer, $v_read_size);
5592
        $p_size -= $v_read_size;
5593
      }
5594
    }
5595
    else if ($p_mode==1)
5596
    {
5597 View Code Duplication
      while ($p_size != 0)
5598
      {
5599
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5600
        $v_buffer = @gzread($p_src, $v_read_size);
5601
        @fwrite($p_dest, $v_buffer, $v_read_size);
5602
        $p_size -= $v_read_size;
5603
      }
5604
    }
5605
    else if ($p_mode==2)
5606
    {
5607 View Code Duplication
      while ($p_size != 0)
5608
      {
5609
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5610
        $v_buffer = @fread($p_src, $v_read_size);
5611
        @gzwrite($p_dest, $v_buffer, $v_read_size);
5612
        $p_size -= $v_read_size;
5613
      }
5614
    }
5615
    else if ($p_mode==3)
5616
    {
5617 View Code Duplication
      while ($p_size != 0)
5618
      {
5619
        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5620
        $v_buffer = @gzread($p_src, $v_read_size);
5621
        @gzwrite($p_dest, $v_buffer, $v_read_size);
5622
        $p_size -= $v_read_size;
5623
      }
5624
    }
5625
5626
    // ----- Return
5627
    return $v_result;
5628
  }
5629
  // --------------------------------------------------------------------------------
5630
5631
  // --------------------------------------------------------------------------------
5632
  // Function : PclZipUtilRename()
5633
  // Description :
5634
  //   This function tries to do a simple rename() function. If it fails, it
5635
  //   tries to copy the $p_src file in a new $p_dest file and then unlink the
5636
  //   first one.
5637
  // Parameters :
5638
  //   $p_src : Old filename
5639
  //   $p_dest : New filename
5640
  // Return Values :
5641
  //   1 on success, 0 on failure.
5642
  // --------------------------------------------------------------------------------
5643
  function PclZipUtilRename($p_src, $p_dest)
5644
  {
5645
    $v_result = 1;
5646
5647
    // ----- Try to rename the files
5648
    if (!@rename($p_src, $p_dest)) {
5649
5650
      // ----- Try to copy & unlink the src
5651
      if (!@copy($p_src, $p_dest)) {
5652
        $v_result = 0;
5653
      }
5654
      else if (!@unlink($p_src)) {
5655
        $v_result = 0;
5656
      }
5657
    }
5658
5659
    // ----- Return
5660
    return $v_result;
5661
  }
5662
  // --------------------------------------------------------------------------------
5663
5664
  // --------------------------------------------------------------------------------
5665
  // Function : PclZipUtilOptionText()
5666
  // Description :
5667
  //   Translate option value in text. Mainly for debug purpose.
5668
  // Parameters :
5669
  //   $p_option : the option value.
5670
  // Return Values :
5671
  //   The option text value.
5672
  // --------------------------------------------------------------------------------
5673
  function PclZipUtilOptionText($p_option)
5674
  {
5675
5676
    $v_list = get_defined_constants();
5677
    for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5678
	    $v_prefix = substr($v_key, 0, 10);
5679
	    if ((   ($v_prefix == 'PCLZIP_OPT')
5680
           || ($v_prefix == 'PCLZIP_CB_')
5681
           || ($v_prefix == 'PCLZIP_ATT'))
5682
	        && ($v_list[$v_key] == $p_option)) {
5683
        return $v_key;
5684
	    }
5685
    }
5686
5687
    $v_result = 'Unknown';
5688
5689
    return $v_result;
5690
  }
5691
  // --------------------------------------------------------------------------------
5692
5693
  // --------------------------------------------------------------------------------
5694
  // Function : PclZipUtilTranslateWinPath()
5695
  // Description :
5696
  //   Translate windows path by replacing '\' by '/' and optionally removing
5697
  //   drive letter.
5698
  // Parameters :
5699
  //   $p_path : path to translate.
5700
  //   $p_remove_disk_letter : true | false
5701
  // Return Values :
5702
  //   The path translated.
5703
  // --------------------------------------------------------------------------------
5704
  function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
5705
  {
5706
    if (stristr(php_uname(), 'windows')) {
5707
      // ----- Look for potential disk letter
5708
      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...
5709
          $p_path = substr($p_path, $v_position+1);
5710
      }
5711
      // ----- Change potential windows directory separator
5712
      if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5713
          $p_path = strtr($p_path, '\\', '/');
5714
      }
5715
    }
5716
    return $p_path;
5717
  }
5718
  // --------------------------------------------------------------------------------
5719
5720
5721
?>
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...
5722