1 <?php
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
30 define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
31 }
32
33
34
35
36
37
38
39
40
41
42
43 if (!defined('PCLZIP_SEPARATOR')) {
44 define( 'PCLZIP_SEPARATOR', ',' );
45 }
46
47
48
49
50
51
52 if (!defined('PCLZIP_ERROR_EXTERNAL')) {
53 define( 'PCLZIP_ERROR_EXTERNAL', 0 );
54 }
55
56
57
58
59
60
61
62
63
64
65 if (!defined('PCLZIP_TEMPORARY_DIR')) {
66 define( 'PCLZIP_TEMPORARY_DIR', '' );
67 }
68
69
70
71
72
73
74
75
76
77 if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
78 define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
79 }
80
81
82
83
84
85
86 $g_pclzip_version = "2.8.2";
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 define( 'PCLZIP_ERR_USER_ABORTED', 2 );
104 define( 'PCLZIP_ERR_NO_ERROR', 0 );
105 define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
106 define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
107 define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
108 define( 'PCLZIP_ERR_MISSING_FILE', -4 );
109 define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
110 define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
111 define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
112 define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
113 define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
114 define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
115 define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
116 define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
117 define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
118 define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
119 define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
120 define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
121 define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
122 define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
123 define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
124 define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
125 define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
126
127
128 define( 'PCLZIP_OPT_PATH', 77001 );
129 define( 'PCLZIP_OPT_ADD_PATH', 77002 );
130 define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
131 define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
132 define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
133 define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
134 define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
135 define( 'PCLZIP_OPT_BY_NAME', 77008 );
136 define( 'PCLZIP_OPT_BY_INDEX', 77009 );
137 define( 'PCLZIP_OPT_BY_EREG', 77010 );
138 define( 'PCLZIP_OPT_BY_PREG', 77011 );
139 define( 'PCLZIP_OPT_COMMENT', 77012 );
140 define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
141 define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
142 define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
143 define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
144 define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
145
146
147
148 define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
149 define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
150 define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 );
151 define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
152 define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 );
153 define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
154 define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 );
155
156
157 define( 'PCLZIP_ATT_FILE_NAME', 79001 );
158 define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
159 define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
160 define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
161 define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
162 define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
163
164
165 define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
166 define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
167 define( 'PCLZIP_CB_PRE_ADD', 78003 );
168 define( 'PCLZIP_CB_POST_ADD', 78004 );
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 class PclZip
191 {
192
193 var $zipname = '';
194
195
196 var $zip_fd = 0;
197
198
199 var $error_code = 1;
200 var $error_string = '';
201
202
203
204
205 var $magic_quotes_status;
206
207
208
209
210
211
212
213
214
215 function PclZip($p_zipname)
216 {
217
218
219 if (!function_exists('gzopen'))
220 {
221 die('Abort '.basename(__FILE__).' : Missing zlib extensions');
222 }
223
224
225 $this->zipname = $p_zipname;
226 $this->zip_fd = 0;
227 $this->magic_quotes_status = -1;
228
229
230 return;
231 }
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 function create($p_filelist)
272 {
273 $v_result=1;
274
275
276 $this->privErrorReset();
277
278
279 $v_options = array();
280 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
281
282
283 $v_size = func_num_args();
284
285
286 if ($v_size > 1) {
287
288 $v_arg_list = func_get_args();
289
290
291 array_shift($v_arg_list);
292 $v_size--;
293
294
295 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
296
297
298 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
299 array (PCLZIP_OPT_REMOVE_PATH => 'optional',
300 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
301 PCLZIP_OPT_ADD_PATH => 'optional',
302 PCLZIP_CB_PRE_ADD => 'optional',
303 PCLZIP_CB_POST_ADD => 'optional',
304 PCLZIP_OPT_NO_COMPRESSION => 'optional',
305 PCLZIP_OPT_COMMENT => 'optional',
306 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
307 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
308 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
309
310 ));
311 if ($v_result != 1) {
312 return 0;
313 }
314 }
315
316
317
318
319 else {
320
321
322 $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
323
324
325 if ($v_size == 2) {
326 $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
327 }
328 else if ($v_size > 2) {
329 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
330 "Invalid number / type of arguments");
331 return 0;
332 }
333 }
334 }
335
336
337 $this->privOptionDefaultThreshold($v_options);
338
339
340 $v_string_list = array();
341 $v_att_list = array();
342 $v_filedescr_list = array();
343 $p_result_list = array();
344
345
346 if (is_array($p_filelist)) {
347
348
349
350 if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
351 $v_att_list = $p_filelist;
352 }
353
354
355 else {
356 $v_string_list = $p_filelist;
357 }
358 }
359
360
361 else if (is_string($p_filelist)) {
362
363 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
364 }
365
366
367 else {
368 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
369 return 0;
370 }
371
372
373 if (sizeof($v_string_list) != 0) {
374 foreach ($v_string_list as $v_string) {
375 if ($v_string != '') {
376 $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
377 }
378 else {
379 }
380 }
381 }
382
383
384 $v_supported_attributes
385 = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
386 ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
387 ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
388 ,PCLZIP_ATT_FILE_MTIME => 'optional'
389 ,PCLZIP_ATT_FILE_CONTENT => 'optional'
390 ,PCLZIP_ATT_FILE_COMMENT => 'optional'
391 );
392 foreach ($v_att_list as $v_entry) {
393 $v_result = $this->privFileDescrParseAtt($v_entry,
394 $v_filedescr_list[],
395 $v_options,
396 $v_supported_attributes);
397 if ($v_result != 1) {
398 return 0;
399 }
400 }
401
402
403 $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
404 if ($v_result != 1) {
405 return 0;
406 }
407
408
409 $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
410 if ($v_result != 1) {
411 return 0;
412 }
413
414
415 return $p_result_list;
416 }
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454 function add($p_filelist)
455 {
456 $v_result=1;
457
458
459 $this->privErrorReset();
460
461
462 $v_options = array();
463 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
464
465
466 $v_size = func_num_args();
467
468
469 if ($v_size > 1) {
470
471 $v_arg_list = func_get_args();
472
473
474 array_shift($v_arg_list);
475 $v_size--;
476
477
478 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
479
480
481 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
482 array (PCLZIP_OPT_REMOVE_PATH => 'optional',
483 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
484 PCLZIP_OPT_ADD_PATH => 'optional',
485 PCLZIP_CB_PRE_ADD => 'optional',
486 PCLZIP_CB_POST_ADD => 'optional',
487 PCLZIP_OPT_NO_COMPRESSION => 'optional',
488 PCLZIP_OPT_COMMENT => 'optional',
489 PCLZIP_OPT_ADD_COMMENT => 'optional',
490 PCLZIP_OPT_PREPEND_COMMENT => 'optional',
491 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
492 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
493 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
494
495 ));
496 if ($v_result != 1) {
497 return 0;
498 }
499 }
500
501
502
503
504 else {
505
506
507 $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
508
509
510 if ($v_size == 2) {
511 $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
512 }
513 else if ($v_size > 2) {
514
515 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
516
517
518 return 0;
519 }
520 }
521 }
522
523
524 $this->privOptionDefaultThreshold($v_options);
525
526
527 $v_string_list = array();
528 $v_att_list = array();
529 $v_filedescr_list = array();
530 $p_result_list = array();
531
532
533 if (is_array($p_filelist)) {
534
535
536
537 if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
538 $v_att_list = $p_filelist;
539 }
540
541
542 else {
543 $v_string_list = $p_filelist;
544 }
545 }
546
547
548 else if (is_string($p_filelist)) {
549
550 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
551 }
552
553
554 else {
555 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
556 return 0;
557 }
558
559
560 if (sizeof($v_string_list) != 0) {
561 foreach ($v_string_list as $v_string) {
562 $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
563 }
564 }
565
566
567 $v_supported_attributes
568 = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
569 ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
570 ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
571 ,PCLZIP_ATT_FILE_MTIME => 'optional'
572 ,PCLZIP_ATT_FILE_CONTENT => 'optional'
573 ,PCLZIP_ATT_FILE_COMMENT => 'optional'
574 );
575 foreach ($v_att_list as $v_entry) {
576 $v_result = $this->privFileDescrParseAtt($v_entry,
577 $v_filedescr_list[],
578 $v_options,
579 $v_supported_attributes);
580 if ($v_result != 1) {
581 return 0;
582 }
583 }
584
585
586 $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
587 if ($v_result != 1) {
588 return 0;
589 }
590
591
592 $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
593 if ($v_result != 1) {
594 return 0;
595 }
596
597
598 return $p_result_list;
599 }
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643 function listContent()
644 {
645 $v_result=1;
646
647
648 $this->privErrorReset();
649
650
651 if (!$this->privCheckFormat()) {
652 return(0);
653 }
654
655
656 $p_list = array();
657 if (($v_result = $this->privList($p_list)) != 1)
658 {
659 unset($p_list);
660 return(0);
661 }
662
663
664 return $p_list;
665 }
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700 function extract()
701 {
702 $v_result=1;
703
704
705 $this->privErrorReset();
706
707
708 if (!$this->privCheckFormat()) {
709 return(0);
710 }
711
712
713 $v_options = array();
714
715 $v_path = '';
716 $v_remove_path = "";
717 $v_remove_all_path = false;
718
719
720 $v_size = func_num_args();
721
722
723 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
724
725
726 if ($v_size > 0) {
727
728 $v_arg_list = func_get_args();
729
730
731 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
732
733
734 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
735 array (PCLZIP_OPT_PATH => 'optional',
736 PCLZIP_OPT_REMOVE_PATH => 'optional',
737 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
738 PCLZIP_OPT_ADD_PATH => 'optional',
739 PCLZIP_CB_PRE_EXTRACT => 'optional',
740 PCLZIP_CB_POST_EXTRACT => 'optional',
741 PCLZIP_OPT_SET_CHMOD => 'optional',
742 PCLZIP_OPT_BY_NAME => 'optional',
743 PCLZIP_OPT_BY_EREG => 'optional',
744 PCLZIP_OPT_BY_PREG => 'optional',
745 PCLZIP_OPT_BY_INDEX => 'optional',
746 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
747 PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
748 PCLZIP_OPT_REPLACE_NEWER => 'optional'
749 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
750 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
751 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
752 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
753 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
754 ));
755 if ($v_result != 1) {
756 return 0;
757 }
758
759
760 if (isset($v_options[PCLZIP_OPT_PATH])) {
761 $v_path = $v_options[PCLZIP_OPT_PATH];
762 }
763 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
764 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
765 }
766 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
767 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
768 }
769 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
770
771 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
772 $v_path .= '/';
773 }
774 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
775 }
776 }
777
778
779
780
781 else {
782
783
784 $v_path = $v_arg_list[0];
785
786
787 if ($v_size == 2) {
788 $v_remove_path = $v_arg_list[1];
789 }
790 else if ($v_size > 2) {
791
792 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
793
794
795 return 0;
796 }
797 }
798 }
799
800
801 $this->privOptionDefaultThreshold($v_options);
802
803
804
805
806 $p_list = array();
807 $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
808 $v_remove_all_path, $v_options);
809 if ($v_result < 1) {
810 unset($p_list);
811 return(0);
812 }
813
814
815 return $p_list;
816 }
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857 function extractByIndex($p_index)
858 {
859 $v_result=1;
860
861
862 $this->privErrorReset();
863
864
865 if (!$this->privCheckFormat()) {
866 return(0);
867 }
868
869
870 $v_options = array();
871
872 $v_path = '';
873 $v_remove_path = "";
874 $v_remove_all_path = false;
875
876
877 $v_size = func_num_args();
878
879
880 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
881
882
883 if ($v_size > 1) {
884
885 $v_arg_list = func_get_args();
886
887
888 array_shift($v_arg_list);
889 $v_size--;
890
891
892 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
893
894
895 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
896 array (PCLZIP_OPT_PATH => 'optional',
897 PCLZIP_OPT_REMOVE_PATH => 'optional',
898 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
899 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
900 PCLZIP_OPT_ADD_PATH => 'optional',
901 PCLZIP_CB_PRE_EXTRACT => 'optional',
902 PCLZIP_CB_POST_EXTRACT => 'optional',
903 PCLZIP_OPT_SET_CHMOD => 'optional',
904 PCLZIP_OPT_REPLACE_NEWER => 'optional'
905 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
906 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
907 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
908 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
909 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
910 ));
911 if ($v_result != 1) {
912 return 0;
913 }
914
915
916 if (isset($v_options[PCLZIP_OPT_PATH])) {
917 $v_path = $v_options[PCLZIP_OPT_PATH];
918 }
919 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
920 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
921 }
922 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
923 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
924 }
925 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
926
927 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
928 $v_path .= '/';
929 }
930 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
931 }
932 if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
933 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
934 }
935 else {
936 }
937 }
938
939
940
941
942 else {
943
944
945 $v_path = $v_arg_list[0];
946
947
948 if ($v_size == 2) {
949 $v_remove_path = $v_arg_list[1];
950 }
951 else if ($v_size > 2) {
952
953 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
954
955
956 return 0;
957 }
958 }
959 }
960
961
962
963
964
965
966 $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
967 $v_options_trick = array();
968 $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
969 array (PCLZIP_OPT_BY_INDEX => 'optional' ));
970 if ($v_result != 1) {
971 return 0;
972 }
973 $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
974
975
976 $this->privOptionDefaultThreshold($v_options);
977
978
979 if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
980 return(0);
981 }
982
983
984 return $p_list;
985 }
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006 function delete()
1007 {
1008 $v_result=1;
1009
1010
1011 $this->privErrorReset();
1012
1013
1014 if (!$this->privCheckFormat()) {
1015 return(0);
1016 }
1017
1018
1019 $v_options = array();
1020
1021
1022 $v_size = func_num_args();
1023
1024
1025 if ($v_size > 0) {
1026
1027 $v_arg_list = func_get_args();
1028
1029
1030 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1031 array (PCLZIP_OPT_BY_NAME => 'optional',
1032 PCLZIP_OPT_BY_EREG => 'optional',
1033 PCLZIP_OPT_BY_PREG => 'optional',
1034 PCLZIP_OPT_BY_INDEX => 'optional' ));
1035 if ($v_result != 1) {
1036 return 0;
1037 }
1038 }
1039
1040
1041 $this->privDisableMagicQuotes();
1042
1043
1044 $v_list = array();
1045 if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1046 $this->privSwapBackMagicQuotes();
1047 unset($v_list);
1048 return(0);
1049 }
1050
1051
1052 $this->privSwapBackMagicQuotes();
1053
1054
1055 return $v_list;
1056 }
1057
1058
1059
1060
1061
1062
1063
1064
1065 function deleteByIndex($p_index)
1066 {
1067
1068 $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1069
1070
1071 return $p_list;
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089 function properties()
1090 {
1091
1092
1093 $this->privErrorReset();
1094
1095
1096 $this->privDisableMagicQuotes();
1097
1098
1099 if (!$this->privCheckFormat()) {
1100 $this->privSwapBackMagicQuotes();
1101 return(0);
1102 }
1103
1104
1105 $v_prop = array();
1106 $v_prop['comment'] = '';
1107 $v_prop['nb'] = 0;
1108 $v_prop['status'] = 'not_exist';
1109
1110
1111 if (@is_file($this->zipname))
1112 {
1113
1114 if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1115 {
1116 $this->privSwapBackMagicQuotes();
1117
1118
1119 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1120
1121
1122 return 0;
1123 }
1124
1125
1126 $v_central_dir = array();
1127 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1128 {
1129 $this->privSwapBackMagicQuotes();
1130 return 0;
1131 }
1132
1133
1134 $this->privCloseFd();
1135
1136
1137 $v_prop['comment'] = $v_central_dir['comment'];
1138 $v_prop['nb'] = $v_central_dir['entries'];
1139 $v_prop['status'] = 'ok';
1140 }
1141
1142
1143 $this->privSwapBackMagicQuotes();
1144
1145
1146 return $v_prop;
1147 }
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 function duplicate($p_archive)
1163 {
1164 $v_result = 1;
1165
1166
1167 $this->privErrorReset();
1168
1169
1170 if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1171 {
1172
1173
1174 $v_result = $this->privDuplicate($p_archive->zipname);
1175 }
1176
1177
1178 else if (is_string($p_archive))
1179 {
1180
1181
1182
1183 if (!is_file($p_archive)) {
1184
1185 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1186 $v_result = PCLZIP_ERR_MISSING_FILE;
1187 }
1188 else {
1189
1190 $v_result = $this->privDuplicate($p_archive);
1191 }
1192 }
1193
1194
1195 else
1196 {
1197
1198 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1199 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1200 }
1201
1202
1203 return $v_result;
1204 }
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221 function merge($p_archive_to_add)
1222 {
1223 $v_result = 1;
1224
1225
1226 $this->privErrorReset();
1227
1228
1229 if (!$this->privCheckFormat()) {
1230 return(0);
1231 }
1232
1233
1234 if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1235 {
1236
1237
1238 $v_result = $this->privMerge($p_archive_to_add);
1239 }
1240
1241
1242 else if (is_string($p_archive_to_add))
1243 {
1244
1245
1246 $v_object_archive = new PclZip($p_archive_to_add);
1247
1248
1249 $v_result = $this->privMerge($v_object_archive);
1250 }
1251
1252
1253 else
1254 {
1255
1256 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1257 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1258 }
1259
1260
1261 return $v_result;
1262 }
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 function errorCode()
1273 {
1274 if (PCLZIP_ERROR_EXTERNAL == 1) {
1275 return(PclErrorCode());
1276 }
1277 else {
1278 return($this->error_code);
1279 }
1280 }
1281
1282
1283
1284
1285
1286
1287
1288 function errorName($p_with_code=false)
1289 {
1290 $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1291 PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1292 PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1293 PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1294 PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1295 PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1296 PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1297 PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1298 PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1299 PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1300 PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1301 PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1302 PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1303 PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1304 PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1305 PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1306 PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1307 PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1308 PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1309 ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1310 ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1311 );
1312
1313 if (isset($v_name[$this->error_code])) {
1314 $v_value = $v_name[$this->error_code];
1315 }
1316 else {
1317 $v_value = 'NoName';
1318 }
1319
1320 if ($p_with_code) {
1321 return($v_value.' ('.$this->error_code.')');
1322 }
1323 else {
1324 return($v_value);
1325 }
1326 }
1327
1328
1329
1330
1331
1332
1333
1334 function errorInfo($p_full=false)
1335 {
1336 if (PCLZIP_ERROR_EXTERNAL == 1) {
1337 return(PclErrorString());
1338 }
1339 else {
1340 if ($p_full) {
1341 return($this->errorName(true)." : ".$this->error_string);
1342 }
1343 else {
1344 return($this->error_string." [code ".$this->error_code."]");
1345 }
1346 }
1347 }
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373 function privCheckFormat($p_level=0)
1374 {
1375 $v_result = true;
1376
1377
1378 clearstatcache();
1379
1380
1381 $this->privErrorReset();
1382
1383
1384 if (!is_file($this->zipname)) {
1385
1386 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1387 return(false);
1388 }
1389
1390
1391 if (!is_readable($this->zipname)) {
1392
1393 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1394 return(false);
1395 }
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407 return $v_result;
1408 }
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426 function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1427 {
1428 $v_result=1;
1429
1430
1431 $i=0;
1432 while ($i<$p_size) {
1433
1434
1435 if (!isset($v_requested_options[$p_options_list[$i]])) {
1436
1437 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1438
1439
1440 return PclZip::errorCode();
1441 }
1442
1443
1444 switch ($p_options_list[$i]) {
1445
1446 case PCLZIP_OPT_PATH :
1447 case PCLZIP_OPT_REMOVE_PATH :
1448 case PCLZIP_OPT_ADD_PATH :
1449
1450 if (($i+1) >= $p_size) {
1451
1452 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1453
1454
1455 return PclZip::errorCode();
1456 }
1457
1458
1459 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1460 $i++;
1461 break;
1462
1463 case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
1464
1465 if (($i+1) >= $p_size) {
1466 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1467 return PclZip::errorCode();
1468 }
1469
1470
1471 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1472 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1473 return PclZip::errorCode();
1474 }
1475
1476
1477 $v_value = $p_options_list[$i+1];
1478 if ((!is_integer($v_value)) || ($v_value<0)) {
1479 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1480 return PclZip::errorCode();
1481 }
1482
1483
1484 $v_result_list[$p_options_list[$i]] = $v_value*1048576;
1485 $i++;
1486 break;
1487
1488 case PCLZIP_OPT_TEMP_FILE_ON :
1489
1490 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1491 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1492 return PclZip::errorCode();
1493 }
1494
1495 $v_result_list[$p_options_list[$i]] = true;
1496 break;
1497
1498 case PCLZIP_OPT_TEMP_FILE_OFF :
1499
1500 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1501 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1502 return PclZip::errorCode();
1503 }
1504
1505 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1506 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1507 return PclZip::errorCode();
1508 }
1509
1510 $v_result_list[$p_options_list[$i]] = true;
1511 break;
1512
1513 case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1514
1515 if (($i+1) >= $p_size) {
1516
1517 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1518
1519
1520 return PclZip::errorCode();
1521 }
1522
1523
1524 if ( is_string($p_options_list[$i+1])
1525 && ($p_options_list[$i+1] != '')) {
1526 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1527 $i++;
1528 }
1529 else {
1530 }
1531 break;
1532
1533
1534 case PCLZIP_OPT_BY_NAME :
1535
1536 if (($i+1) >= $p_size) {
1537
1538 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1539
1540
1541 return PclZip::errorCode();
1542 }
1543
1544
1545 if (is_string($p_options_list[$i+1])) {
1546 $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1547 }
1548 else if (is_array($p_options_list[$i+1])) {
1549 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1550 }
1551 else {
1552
1553 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1554
1555
1556 return PclZip::errorCode();
1557 }
1558 $i++;
1559 break;
1560
1561
1562 case PCLZIP_OPT_BY_EREG :
1563
1564
1565 $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1566 case PCLZIP_OPT_BY_PREG :
1567
1568
1569 if (($i+1) >= $p_size) {
1570
1571 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1572
1573
1574 return PclZip::errorCode();
1575 }
1576
1577
1578 if (is_string($p_options_list[$i+1])) {
1579 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1580 }
1581 else {
1582
1583 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1584
1585
1586 return PclZip::errorCode();
1587 }
1588 $i++;
1589 break;
1590
1591
1592 case PCLZIP_OPT_COMMENT :
1593 case PCLZIP_OPT_ADD_COMMENT :
1594 case PCLZIP_OPT_PREPEND_COMMENT :
1595
1596 if (($i+1) >= $p_size) {
1597
1598 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1599 "Missing parameter value for option '"
1600 .PclZipUtilOptionText($p_options_list[$i])
1601 ."'");
1602
1603
1604 return PclZip::errorCode();
1605 }
1606
1607
1608 if (is_string($p_options_list[$i+1])) {
1609 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1610 }
1611 else {
1612
1613 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1614 "Wrong parameter value for option '"
1615 .PclZipUtilOptionText($p_options_list[$i])
1616 ."'");
1617
1618
1619 return PclZip::errorCode();
1620 }
1621 $i++;
1622 break;
1623
1624
1625 case PCLZIP_OPT_BY_INDEX :
1626
1627 if (($i+1) >= $p_size) {
1628
1629 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1630
1631
1632 return PclZip::errorCode();
1633 }
1634
1635
1636 $v_work_list = array();
1637 if (is_string($p_options_list[$i+1])) {
1638
1639
1640 $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1641
1642
1643 $v_work_list = explode(",", $p_options_list[$i+1]);
1644 }
1645 else if (is_integer($p_options_list[$i+1])) {
1646 $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1647 }
1648 else if (is_array($p_options_list[$i+1])) {
1649 $v_work_list = $p_options_list[$i+1];
1650 }
1651 else {
1652
1653 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1654
1655
1656 return PclZip::errorCode();
1657 }
1658
1659
1660
1661
1662
1663 $v_sort_flag=false;
1664 $v_sort_value=0;
1665 for ($j=0; $j<sizeof($v_work_list); $j++) {
1666
1667 $v_item_list = explode("-", $v_work_list[$j]);
1668 $v_size_item_list = sizeof($v_item_list);
1669
1670
1671
1672
1673
1674 if ($v_size_item_list == 1) {
1675
1676 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1677 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1678 }
1679 elseif ($v_size_item_list == 2) {
1680
1681 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1682 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1683 }
1684 else {
1685
1686 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1687
1688
1689 return PclZip::errorCode();
1690 }
1691
1692
1693
1694 if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1695 $v_sort_flag=true;
1696
1697
1698
1699 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1700
1701
1702 return PclZip::errorCode();
1703 }
1704 $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1705 }
1706
1707
1708 if ($v_sort_flag) {
1709
1710 }
1711
1712
1713 $i++;
1714 break;
1715
1716
1717 case PCLZIP_OPT_REMOVE_ALL_PATH :
1718 case PCLZIP_OPT_EXTRACT_AS_STRING :
1719 case PCLZIP_OPT_NO_COMPRESSION :
1720 case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1721 case PCLZIP_OPT_REPLACE_NEWER :
1722 case PCLZIP_OPT_STOP_ON_ERROR :
1723 $v_result_list[$p_options_list[$i]] = true;
1724 break;
1725
1726
1727 case PCLZIP_OPT_SET_CHMOD :
1728
1729 if (($i+1) >= $p_size) {
1730
1731 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1732
1733
1734 return PclZip::errorCode();
1735 }
1736
1737
1738 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1739 $i++;
1740 break;
1741
1742
1743 case PCLZIP_CB_PRE_EXTRACT :
1744 case PCLZIP_CB_POST_EXTRACT :
1745 case PCLZIP_CB_PRE_ADD :
1746 case PCLZIP_CB_POST_ADD :
1747
1748
1749
1750
1751
1752
1753
1754 if (($i+1) >= $p_size) {
1755
1756 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1757
1758
1759 return PclZip::errorCode();
1760 }
1761
1762
1763 $v_function_name = $p_options_list[$i+1];
1764
1765
1766 if (!function_exists($v_function_name)) {
1767
1768 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1769
1770
1771 return PclZip::errorCode();
1772 }
1773
1774
1775 $v_result_list[$p_options_list[$i]] = $v_function_name;
1776 $i++;
1777 break;
1778
1779 default :
1780
1781 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1782 "Unknown parameter '"
1783 .$p_options_list[$i]."'");
1784
1785
1786 return PclZip::errorCode();
1787 }
1788
1789
1790 $i++;
1791 }
1792
1793
1794 if ($v_requested_options !== false) {
1795 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1796
1797 if ($v_requested_options[$key] == 'mandatory') {
1798
1799 if (!isset($v_result_list[$key])) {
1800
1801 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1802
1803
1804 return PclZip::errorCode();
1805 }
1806 }
1807 }
1808 }
1809
1810
1811 if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1812
1813 }
1814
1815
1816 return $v_result;
1817 }
1818
1819
1820
1821
1822
1823
1824
1825
1826 function privOptionDefaultThreshold(&$p_options)
1827 {
1828 $v_result=1;
1829
1830 if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1831 || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1832 return $v_result;
1833 }
1834
1835
1836 $v_memory_limit = ini_get('memory_limit');
1837 $v_memory_limit = trim($v_memory_limit);
1838 $last = strtolower(substr($v_memory_limit, -1));
1839
1840 if($last == 'g')
1841
1842 $v_memory_limit = $v_memory_limit*1073741824;
1843 if($last == 'm')
1844
1845 $v_memory_limit = $v_memory_limit*1048576;
1846 if($last == 'k')
1847 $v_memory_limit = $v_memory_limit*1024;
1848
1849 $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
1850
1851
1852
1853 if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1854 unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1855 }
1856
1857
1858 return $v_result;
1859 }
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870 function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1871 {
1872 $v_result=1;
1873
1874
1875 foreach ($p_file_list as $v_key => $v_value) {
1876
1877
1878 if (!isset($v_requested_options[$v_key])) {
1879
1880 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1881
1882
1883 return PclZip::errorCode();
1884 }
1885
1886
1887 switch ($v_key) {
1888 case PCLZIP_ATT_FILE_NAME :
1889 if (!is_string($v_value)) {
1890 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1891 return PclZip::errorCode();
1892 }
1893
1894 $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1895
1896 if ($p_filedescr['filename'] == '') {
1897 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1898 return PclZip::errorCode();
1899 }
1900
1901 break;
1902
1903 case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1904 if (!is_string($v_value)) {
1905 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1906 return PclZip::errorCode();
1907 }
1908
1909 $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1910
1911 if ($p_filedescr['new_short_name'] == '') {
1912 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1913 return PclZip::errorCode();
1914 }
1915 break;
1916
1917 case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1918 if (!is_string($v_value)) {
1919 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1920 return PclZip::errorCode();
1921 }
1922
1923 $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1924
1925 if ($p_filedescr['new_full_name'] == '') {
1926 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1927 return PclZip::errorCode();
1928 }
1929 break;
1930
1931
1932 case PCLZIP_ATT_FILE_COMMENT :
1933 if (!is_string($v_value)) {
1934 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1935 return PclZip::errorCode();
1936 }
1937
1938 $p_filedescr['comment'] = $v_value;
1939 break;
1940
1941 case PCLZIP_ATT_FILE_MTIME :
1942 if (!is_integer($v_value)) {
1943 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1944 return PclZip::errorCode();
1945 }
1946
1947 $p_filedescr['mtime'] = $v_value;
1948 break;
1949
1950 case PCLZIP_ATT_FILE_CONTENT :
1951 $p_filedescr['content'] = $v_value;
1952 break;
1953
1954 default :
1955
1956 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1957 "Unknown parameter '".$v_key."'");
1958
1959
1960 return PclZip::errorCode();
1961 }
1962
1963
1964 if ($v_requested_options !== false) {
1965 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1966
1967 if ($v_requested_options[$key] == 'mandatory') {
1968
1969 if (!isset($p_file_list[$key])) {
1970 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1971 return PclZip::errorCode();
1972 }
1973 }
1974 }
1975 }
1976
1977
1978 }
1979
1980
1981 return $v_result;
1982 }
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999 function privFileDescrExpand(&$p_filedescr_list, &$p_options)
2000 {
2001 $v_result=1;
2002
2003
2004 $v_result_list = array();
2005
2006
2007 for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
2008
2009
2010 $v_descr = $p_filedescr_list[$i];
2011
2012
2013 $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
2014 $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
2015
2016
2017 if (file_exists($v_descr['filename'])) {
2018 if (@is_file($v_descr['filename'])) {
2019 $v_descr['type'] = 'file';
2020 }
2021 else if (@is_dir($v_descr['filename'])) {
2022 $v_descr['type'] = 'folder';
2023 }
2024 else if (@is_link($v_descr['filename'])) {
2025
2026 continue;
2027 }
2028 else {
2029
2030 continue;
2031 }
2032 }
2033
2034
2035 else if (isset($v_descr['content'])) {
2036 $v_descr['type'] = 'virtual_file';
2037 }
2038
2039
2040 else {
2041
2042 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
2043
2044
2045 return PclZip::errorCode();
2046 }
2047
2048
2049 $this->privCalculateStoredFilename($v_descr, $p_options);
2050
2051
2052 $v_result_list[sizeof($v_result_list)] = $v_descr;
2053
2054
2055 if ($v_descr['type'] == 'folder') {
2056
2057 $v_dirlist_descr = array();
2058 $v_dirlist_nb = 0;
2059 if ($v_folder_handler = @opendir($v_descr['filename'])) {
2060 while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2061
2062
2063 if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2064 continue;
2065 }
2066
2067
2068 $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2069
2070
2071
2072
2073 if (($v_descr['stored_filename'] != $v_descr['filename'])
2074 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2075 if ($v_descr['stored_filename'] != '') {
2076 $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2077 }
2078 else {
2079 $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2080 }
2081 }
2082
2083 $v_dirlist_nb++;
2084 }
2085
2086 @closedir($v_folder_handler);
2087 }
2088 else {
2089
2090 }
2091
2092
2093 if ($v_dirlist_nb != 0) {
2094
2095 if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2096 return $v_result;
2097 }
2098
2099
2100 $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2101 }
2102 else {
2103 }
2104
2105
2106 unset($v_dirlist_descr);
2107 }
2108 }
2109
2110
2111 $p_filedescr_list = $v_result_list;
2112
2113
2114 return $v_result;
2115 }
2116
2117
2118
2119
2120
2121
2122
2123
2124 function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2125 {
2126 $v_result=1;
2127 $v_list_detail = array();
2128
2129
2130 $this->privDisableMagicQuotes();
2131
2132
2133 if (($v_result = $this->privOpenFd('wb')) != 1)
2134 {
2135
2136 return $v_result;
2137 }
2138
2139
2140 $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2141
2142
2143 $this->privCloseFd();
2144
2145
2146 $this->privSwapBackMagicQuotes();
2147
2148
2149 return $v_result;
2150 }
2151
2152
2153
2154
2155
2156
2157
2158
2159 function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2160 {
2161 $v_result=1;
2162 $v_list_detail = array();
2163
2164
2165 if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2166 {
2167
2168
2169 $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2170
2171
2172 return $v_result;
2173 }
2174
2175 $this->privDisableMagicQuotes();
2176
2177
2178 if (($v_result=$this->privOpenFd('rb')) != 1)
2179 {
2180
2181 $this->privSwapBackMagicQuotes();
2182
2183
2184 return $v_result;
2185 }
2186
2187
2188 $v_central_dir = array();
2189 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2190 {
2191 $this->privCloseFd();
2192 $this->privSwapBackMagicQuotes();
2193 return $v_result;
2194 }
2195
2196
2197 @rewind($this->zip_fd);
2198
2199
2200 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2201
2202
2203 if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2204 {
2205 $this->privCloseFd();
2206 $this->privSwapBackMagicQuotes();
2207
2208 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2209
2210
2211 return PclZip::errorCode();
2212 }
2213
2214
2215
2216 $v_size = $v_central_dir['offset'];
2217 while ($v_size != 0)
2218 {
2219 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2220 $v_buffer = fread($this->zip_fd, $v_read_size);
2221 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2222 $v_size -= $v_read_size;
2223 }
2224
2225
2226
2227
2228 $v_swap = $this->zip_fd;
2229 $this->zip_fd = $v_zip_temp_fd;
2230 $v_zip_temp_fd = $v_swap;
2231
2232
2233 $v_header_list = array();
2234 if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2235 {
2236 fclose($v_zip_temp_fd);
2237 $this->privCloseFd();
2238 @unlink($v_zip_temp_name);
2239 $this->privSwapBackMagicQuotes();
2240
2241
2242 return $v_result;
2243 }
2244
2245
2246 $v_offset = @ftell($this->zip_fd);
2247
2248
2249 $v_size = $v_central_dir['size'];
2250 while ($v_size != 0)
2251 {
2252 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2253 $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2254 @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2255 $v_size -= $v_read_size;
2256 }
2257
2258
2259 for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2260 {
2261
2262 if ($v_header_list[$i]['status'] == 'ok') {
2263 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2264 fclose($v_zip_temp_fd);
2265 $this->privCloseFd();
2266 @unlink($v_zip_temp_name);
2267 $this->privSwapBackMagicQuotes();
2268
2269
2270 return $v_result;
2271 }
2272 $v_count++;
2273 }
2274
2275
2276 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2277 }
2278
2279
2280 $v_comment = $v_central_dir['comment'];
2281 if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2282 $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2283 }
2284 if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2285 $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2286 }
2287 if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2288 $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2289 }
2290
2291
2292 $v_size = @ftell($this->zip_fd)-$v_offset;
2293
2294
2295 if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2296 {
2297
2298 unset($v_header_list);
2299 $this->privSwapBackMagicQuotes();
2300
2301
2302 return $v_result;
2303 }
2304
2305
2306 $v_swap = $this->zip_fd;
2307 $this->zip_fd = $v_zip_temp_fd;
2308 $v_zip_temp_fd = $v_swap;
2309
2310
2311 $this->privCloseFd();
2312
2313
2314 @fclose($v_zip_temp_fd);
2315
2316
2317 $this->privSwapBackMagicQuotes();
2318
2319
2320
2321 @unlink($this->zipname);
2322
2323
2324
2325
2326 PclZipUtilRename($v_zip_temp_name, $this->zipname);
2327
2328
2329 return $v_result;
2330 }
2331
2332
2333
2334
2335
2336
2337
2338 function privOpenFd($p_mode)
2339 {
2340 $v_result=1;
2341
2342
2343 if ($this->zip_fd != 0)
2344 {
2345
2346 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2347
2348
2349 return PclZip::errorCode();
2350 }
2351
2352
2353 if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2354 {
2355
2356 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2357
2358
2359 return PclZip::errorCode();
2360 }
2361
2362
2363 return $v_result;
2364 }
2365
2366
2367
2368
2369
2370
2371
2372 function privCloseFd()
2373 {
2374 $v_result=1;
2375
2376 if ($this->zip_fd != 0)
2377 @fclose($this->zip_fd);
2378 $this->zip_fd = 0;
2379
2380
2381 return $v_result;
2382 }
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399 function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2400 {
2401 $v_result=1;
2402
2403
2404 $v_header_list = array();
2405 if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2406 {
2407
2408 return $v_result;
2409 }
2410
2411
2412 $v_offset = @ftell($this->zip_fd);
2413
2414
2415 for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2416 {
2417
2418 if ($v_header_list[$i]['status'] == 'ok') {
2419 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2420
2421 return $v_result;
2422 }
2423 $v_count++;
2424 }
2425
2426
2427 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2428 }
2429
2430
2431 $v_comment = '';
2432 if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2433 $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2434 }
2435
2436
2437 $v_size = @ftell($this->zip_fd)-$v_offset;
2438
2439
2440 if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2441 {
2442
2443 unset($v_header_list);
2444
2445
2446 return $v_result;
2447 }
2448
2449
2450 return $v_result;
2451 }
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463 function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2464 {
2465 $v_result=1;
2466 $v_header = array();
2467
2468
2469 $v_nb = sizeof($p_result_list);
2470
2471
2472 for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2473
2474 $p_filedescr_list[$j]['filename']
2475 = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2476
2477
2478
2479
2480 if ($p_filedescr_list[$j]['filename'] == "") {
2481 continue;
2482 }
2483
2484
2485 if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
2486 && (!file_exists($p_filedescr_list[$j]['filename']))) {
2487 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
2488 return PclZip::errorCode();
2489 }
2490
2491
2492
2493
2494
2495 if ( ($p_filedescr_list[$j]['type'] == 'file')
2496 || ($p_filedescr_list[$j]['type'] == 'virtual_file')
2497 || ( ($p_filedescr_list[$j]['type'] == 'folder')
2498 && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2499 || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
2500 ) {
2501
2502
2503 $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2504 $p_options);
2505 if ($v_result != 1) {
2506 return $v_result;
2507 }
2508
2509
2510 $p_result_list[$v_nb++] = $v_header;
2511 }
2512 }
2513
2514
2515 return $v_result;
2516 }
2517
2518
2519
2520
2521
2522
2523
2524
2525 function privAddFile($p_filedescr, &$p_header, &$p_options)
2526 {
2527 $v_result=1;
2528
2529
2530 $p_filename = $p_filedescr['filename'];
2531
2532
2533 if ($p_filename == "") {
2534
2535 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2536
2537
2538 return PclZip::errorCode();
2539 }
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552 clearstatcache();
2553 $p_header['version'] = 20;
2554 $p_header['version_extracted'] = 10;
2555 $p_header['flag'] = 0;
2556 $p_header['compression'] = 0;
2557 $p_header['crc'] = 0;
2558 $p_header['compressed_size'] = 0;
2559 $p_header['filename_len'] = strlen($p_filename);
2560 $p_header['extra_len'] = 0;
2561 $p_header['disk'] = 0;
2562 $p_header['internal'] = 0;
2563 $p_header['offset'] = 0;
2564 $p_header['filename'] = $p_filename;
2565
2566 $p_header['stored_filename'] = $p_filedescr['stored_filename'];
2567 $p_header['extra'] = '';
2568 $p_header['status'] = 'ok';
2569 $p_header['index'] = -1;
2570
2571
2572 if ($p_filedescr['type']=='file') {
2573 $p_header['external'] = 0x00000000;
2574 $p_header['size'] = filesize($p_filename);
2575 }
2576
2577
2578 else if ($p_filedescr['type']=='folder') {
2579 $p_header['external'] = 0x00000010;
2580 $p_header['mtime'] = filemtime($p_filename);
2581 $p_header['size'] = filesize($p_filename);
2582 }
2583
2584
2585 else if ($p_filedescr['type'] == 'virtual_file') {
2586 $p_header['external'] = 0x00000000;
2587 $p_header['size'] = strlen($p_filedescr['content']);
2588 }
2589
2590
2591
2592 if (isset($p_filedescr['mtime'])) {
2593 $p_header['mtime'] = $p_filedescr['mtime'];
2594 }
2595 else if ($p_filedescr['type'] == 'virtual_file') {
2596 $p_header['mtime'] = time();
2597 }
2598 else {
2599 $p_header['mtime'] = filemtime($p_filename);
2600 }
2601
2602
2603 if (isset($p_filedescr['comment'])) {
2604 $p_header['comment_len'] = strlen($p_filedescr['comment']);
2605 $p_header['comment'] = $p_filedescr['comment'];
2606 }
2607 else {
2608 $p_header['comment_len'] = 0;
2609 $p_header['comment'] = '';
2610 }
2611
2612
2613 if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2614
2615
2616 $v_local_header = array();
2617 $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2618
2619
2620
2621
2622 $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2623 if ($v_result == 0) {
2624
2625 $p_header['status'] = "skipped";
2626 $v_result = 1;
2627 }
2628
2629
2630
2631 if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2632 $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2633 }
2634 }
2635
2636
2637 if ($p_header['stored_filename'] == "") {
2638 $p_header['status'] = "filtered";
2639 }
2640
2641
2642 if (strlen($p_header['stored_filename']) > 0xFF) {
2643 $p_header['status'] = 'filename_too_long';
2644 }
2645
2646
2647 if ($p_header['status'] == 'ok') {
2648
2649
2650 if ($p_filedescr['type'] == 'file') {
2651
2652 if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
2653 && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2654 || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2655 && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
2656 $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2657 if ($v_result < PCLZIP_ERR_NO_ERROR) {
2658 return $v_result;
2659 }
2660 }
2661
2662
2663 else {
2664
2665
2666 if (($v_file = @fopen($p_filename, "rb")) == 0) {
2667 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2668 return PclZip::errorCode();
2669 }
2670
2671
2672 $v_content = @fread($v_file, $p_header['size']);
2673
2674
2675 @fclose($v_file);
2676
2677
2678 $p_header['crc'] = @crc32($v_content);
2679
2680
2681 if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2682
2683 $p_header['compressed_size'] = $p_header['size'];
2684 $p_header['compression'] = 0;
2685 }
2686
2687
2688 else {
2689
2690 $v_content = @gzdeflate($v_content);
2691
2692
2693 $p_header['compressed_size'] = strlen($v_content);
2694 $p_header['compression'] = 8;
2695 }
2696
2697
2698 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2699 @fclose($v_file);
2700 return $v_result;
2701 }
2702
2703
2704 @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2705
2706 }
2707
2708 }
2709
2710
2711 else if ($p_filedescr['type'] == 'virtual_file') {
2712
2713 $v_content = $p_filedescr['content'];
2714
2715
2716 $p_header['crc'] = @crc32($v_content);
2717
2718
2719 if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2720
2721 $p_header['compressed_size'] = $p_header['size'];
2722 $p_header['compression'] = 0;
2723 }
2724
2725
2726 else {
2727
2728 $v_content = @gzdeflate($v_content);
2729
2730
2731 $p_header['compressed_size'] = strlen($v_content);
2732 $p_header['compression'] = 8;
2733 }
2734
2735
2736 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2737 @fclose($v_file);
2738 return $v_result;
2739 }
2740
2741
2742 @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2743 }
2744
2745
2746 else if ($p_filedescr['type'] == 'folder') {
2747
2748 if (@substr($p_header['stored_filename'], -1) != '/') {
2749 $p_header['stored_filename'] .= '/';
2750 }
2751
2752
2753 $p_header['size'] = 0;
2754
2755 $p_header['external'] = 0x00000010;
2756
2757
2758 if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2759 {
2760 return $v_result;
2761 }
2762 }
2763 }
2764
2765
2766 if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2767
2768
2769 $v_local_header = array();
2770 $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2771
2772
2773
2774
2775 $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2776 if ($v_result == 0) {
2777
2778 $v_result = 1;
2779 }
2780
2781
2782
2783 }
2784
2785
2786 return $v_result;
2787 }
2788
2789
2790
2791
2792
2793
2794
2795
2796 function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
2797 {
2798 $v_result=PCLZIP_ERR_NO_ERROR;
2799
2800
2801 $p_filename = $p_filedescr['filename'];
2802
2803
2804
2805 if (($v_file = @fopen($p_filename, "rb")) == 0) {
2806 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2807 return PclZip::errorCode();
2808 }
2809
2810
2811 $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2812 if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2813 fclose($v_file);
2814 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2815 return PclZip::errorCode();
2816 }
2817
2818
2819 $v_size = filesize($p_filename);
2820 while ($v_size != 0) {
2821 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2822 $v_buffer = @fread($v_file, $v_read_size);
2823
2824 @gzputs($v_file_compressed, $v_buffer, $v_read_size);
2825 $v_size -= $v_read_size;
2826 }
2827
2828
2829 @fclose($v_file);
2830 @gzclose($v_file_compressed);
2831
2832
2833 if (filesize($v_gzip_temp_name) < 18) {
2834 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
2835 return PclZip::errorCode();
2836 }
2837
2838
2839 if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2840 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2841 return PclZip::errorCode();
2842 }
2843
2844
2845 $v_binary_data = @fread($v_file_compressed, 10);
2846 $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
2847
2848
2849 $v_data_header['os'] = bin2hex($v_data_header['os']);
2850
2851
2852 @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
2853 $v_binary_data = @fread($v_file_compressed, 8);
2854 $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2855
2856
2857 $p_header['compression'] = ord($v_data_header['cm']);
2858
2859 $p_header['crc'] = $v_data_footer['crc'];
2860 $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
2861
2862
2863 @fclose($v_file_compressed);
2864
2865
2866 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2867 return $v_result;
2868 }
2869
2870
2871 if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
2872 {
2873 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2874 return PclZip::errorCode();
2875 }
2876
2877
2878 fseek($v_file_compressed, 10);
2879 $v_size = $p_header['compressed_size'];
2880 while ($v_size != 0)
2881 {
2882 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2883 $v_buffer = @fread($v_file_compressed, $v_read_size);
2884
2885 @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2886 $v_size -= $v_read_size;
2887 }
2888
2889
2890 @fclose($v_file_compressed);
2891
2892
2893 @unlink($v_gzip_temp_name);
2894
2895
2896 return $v_result;
2897 }
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908 function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2909 {
2910 $v_result=1;
2911
2912
2913 $p_filename = $p_filedescr['filename'];
2914 if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2915 $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2916 }
2917 else {
2918 $p_add_dir = '';
2919 }
2920 if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2921 $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2922 }
2923 else {
2924 $p_remove_dir = '';
2925 }
2926 if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2927 $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2928 }
2929 else {
2930 $p_remove_all_dir = 0;
2931 }
2932
2933
2934
2935 if (isset($p_filedescr['new_full_name'])) {
2936
2937 $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2938 }
2939
2940
2941 else {
2942
2943
2944
2945 if (isset($p_filedescr['new_short_name'])) {
2946 $v_path_info = pathinfo($p_filename);
2947 $v_dir = '';
2948 if ($v_path_info['dirname'] != '') {
2949 $v_dir = $v_path_info['dirname'].'/';
2950 }
2951 $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2952 }
2953 else {
2954
2955 $v_stored_filename = $p_filename;
2956 }
2957
2958
2959 if ($p_remove_all_dir) {
2960 $v_stored_filename = basename($p_filename);
2961 }
2962
2963 else if ($p_remove_dir != "") {
2964 if (substr($p_remove_dir, -1) != '/')
2965 $p_remove_dir .= "/";
2966
2967 if ( (substr($p_filename, 0, 2) == "./")
2968 || (substr($p_remove_dir, 0, 2) == "./")) {
2969
2970 if ( (substr($p_filename, 0, 2) == "./")
2971 && (substr($p_remove_dir, 0, 2) != "./")) {
2972 $p_remove_dir = "./".$p_remove_dir;
2973 }
2974 if ( (substr($p_filename, 0, 2) != "./")
2975 && (substr($p_remove_dir, 0, 2) == "./")) {
2976 $p_remove_dir = substr($p_remove_dir, 2);
2977 }
2978 }
2979
2980 $v_compare = PclZipUtilPathInclusion($p_remove_dir,
2981 $v_stored_filename);
2982 if ($v_compare > 0) {
2983 if ($v_compare == 2) {
2984 $v_stored_filename = "";
2985 }
2986 else {
2987 $v_stored_filename = substr($v_stored_filename,
2988 strlen($p_remove_dir));
2989 }
2990 }
2991 }
2992
2993
2994 $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
2995
2996
2997 if ($p_add_dir != "") {
2998 if (substr($p_add_dir, -1) == "/")
2999 $v_stored_filename = $p_add_dir.$v_stored_filename;
3000 else
3001 $v_stored_filename = $p_add_dir."/".$v_stored_filename;
3002 }
3003 }
3004
3005
3006 $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
3007 $p_filedescr['stored_filename'] = $v_stored_filename;
3008
3009
3010 return $v_result;
3011 }
3012
3013
3014
3015
3016
3017
3018
3019
3020 function privWriteFileHeader(&$p_header)
3021 {
3022 $v_result=1;
3023
3024
3025 $p_header['offset'] = ftell($this->zip_fd);
3026
3027
3028 $v_date = getdate($p_header['mtime']);
3029 $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3030 $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3031
3032
3033 $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
3034 $p_header['version_extracted'], $p_header['flag'],
3035 $p_header['compression'], $v_mtime, $v_mdate,
3036 $p_header['crc'], $p_header['compressed_size'],
3037 $p_header['size'],
3038 strlen($p_header['stored_filename']),
3039 $p_header['extra_len']);
3040
3041
3042 fputs($this->zip_fd, $v_binary_data, 30);
3043
3044
3045 if (strlen($p_header['stored_filename']) != 0)
3046 {
3047 fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3048 }
3049 if ($p_header['extra_len'] != 0)
3050 {
3051 fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3052 }
3053
3054
3055 return $v_result;
3056 }
3057
3058
3059
3060
3061
3062
3063
3064
3065 function privWriteCentralFileHeader(&$p_header)
3066 {
3067 $v_result=1;
3068
3069
3070
3071
3072
3073
3074 $v_date = getdate($p_header['mtime']);
3075 $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3076 $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3077
3078
3079
3080 $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
3081 $p_header['version'], $p_header['version_extracted'],
3082 $p_header['flag'], $p_header['compression'],
3083 $v_mtime, $v_mdate, $p_header['crc'],
3084 $p_header['compressed_size'], $p_header['size'],
3085 strlen($p_header['stored_filename']),
3086 $p_header['extra_len'], $p_header['comment_len'],
3087 $p_header['disk'], $p_header['internal'],
3088 $p_header['external'], $p_header['offset']);
3089
3090
3091 fputs($this->zip_fd, $v_binary_data, 46);
3092
3093
3094 if (strlen($p_header['stored_filename']) != 0)
3095 {
3096 fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3097 }
3098 if ($p_header['extra_len'] != 0)
3099 {
3100 fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3101 }
3102 if ($p_header['comment_len'] != 0)
3103 {
3104 fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
3105 }
3106
3107
3108 return $v_result;
3109 }
3110
3111
3112
3113
3114
3115
3116
3117
3118 function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3119 {
3120 $v_result=1;
3121
3122
3123 $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
3124 $p_nb_entries, $p_size,
3125 $p_offset, strlen($p_comment));
3126
3127
3128 fputs($this->zip_fd, $v_binary_data, 22);
3129
3130
3131 if (strlen($p_comment) != 0)
3132 {
3133 fputs($this->zip_fd, $p_comment, strlen($p_comment));
3134 }
3135
3136
3137 return $v_result;
3138 }
3139
3140
3141
3142
3143
3144
3145
3146
3147 function privList(&$p_list)
3148 {
3149 $v_result=1;
3150
3151
3152 $this->privDisableMagicQuotes();
3153
3154
3155 if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
3156 {
3157
3158 $this->privSwapBackMagicQuotes();
3159
3160
3161 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
3162
3163
3164 return PclZip::errorCode();
3165 }
3166
3167
3168 $v_central_dir = array();
3169 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3170 {
3171 $this->privSwapBackMagicQuotes();
3172 return $v_result;
3173 }
3174
3175
3176 @rewind($this->zip_fd);
3177 if (@fseek($this->zip_fd, $v_central_dir['offset']))
3178 {
3179 $this->privSwapBackMagicQuotes();
3180
3181
3182 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3183
3184
3185 return PclZip::errorCode();
3186 }
3187
3188
3189 for ($i=0; $i<$v_central_dir['entries']; $i++)
3190 {
3191
3192 if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3193 {
3194 $this->privSwapBackMagicQuotes();
3195 return $v_result;
3196 }
3197 $v_header['index'] = $i;
3198
3199
3200 $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3201 unset($v_header);
3202 }
3203
3204
3205 $this->privCloseFd();
3206
3207
3208 $this->privSwapBackMagicQuotes();
3209
3210
3211 return $v_result;
3212 }
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234 function privConvertHeader2FileInfo($p_header, &$p_info)
3235 {
3236 $v_result=1;
3237
3238
3239 $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
3240 $p_info['filename'] = $v_temp_path;
3241 $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
3242 $p_info['stored_filename'] = $v_temp_path;
3243 $p_info['size'] = $p_header['size'];
3244 $p_info['compressed_size'] = $p_header['compressed_size'];
3245 $p_info['mtime'] = $p_header['mtime'];
3246 $p_info['comment'] = $p_header['comment'];
3247 $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3248 $p_info['index'] = $p_header['index'];
3249 $p_info['status'] = $p_header['status'];
3250 $p_info['crc'] = $p_header['crc'];
3251
3252
3253 return $v_result;
3254 }
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273 function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3274 {
3275 $v_result=1;
3276
3277
3278 $this->privDisableMagicQuotes();
3279
3280
3281 if ( ($p_path == "")
3282 || ( (substr($p_path, 0, 1) != "/")
3283 && (substr($p_path, 0, 3) != "../")
3284 && (substr($p_path,1,2)!=":/")))
3285 $p_path = "./".$p_path;
3286
3287
3288 if (($p_path != "./") && ($p_path != "/"))
3289 {
3290
3291 while (substr($p_path, -1) == "/")
3292 {
3293 $p_path = substr($p_path, 0, strlen($p_path)-1);
3294 }
3295 }
3296
3297
3298 if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3299 {
3300 $p_remove_path .= '/';
3301 }
3302 $p_remove_path_size = strlen($p_remove_path);
3303
3304
3305 if (($v_result = $this->privOpenFd('rb')) != 1)
3306 {
3307 $this->privSwapBackMagicQuotes();
3308 return $v_result;
3309 }
3310
3311
3312 $v_central_dir = array();
3313 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3314 {
3315
3316 $this->privCloseFd();
3317 $this->privSwapBackMagicQuotes();
3318
3319 return $v_result;
3320 }
3321
3322
3323 $v_pos_entry = $v_central_dir['offset'];
3324
3325
3326 $j_start = 0;
3327 for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3328 {
3329
3330
3331 @rewind($this->zip_fd);
3332 if (@fseek($this->zip_fd, $v_pos_entry))
3333 {
3334
3335 $this->privCloseFd();
3336 $this->privSwapBackMagicQuotes();
3337
3338
3339 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3340
3341
3342 return PclZip::errorCode();
3343 }
3344
3345
3346 $v_header = array();
3347 if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3348 {
3349
3350 $this->privCloseFd();
3351 $this->privSwapBackMagicQuotes();
3352
3353 return $v_result;
3354 }
3355
3356
3357 $v_header['index'] = $i;
3358
3359
3360 $v_pos_entry = ftell($this->zip_fd);
3361
3362
3363 $v_extract = false;
3364
3365
3366 if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
3367 && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3368
3369
3370 for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3371
3372
3373 if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3374
3375
3376 if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3377 && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3378 $v_extract = true;
3379 }
3380 }
3381
3382 elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3383 $v_extract = true;
3384 }
3385 }
3386 }
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401 else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
3402 && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3403
3404 if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3405 $v_extract = true;
3406 }
3407 }
3408
3409
3410 else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3411 && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3412
3413
3414 for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3415
3416 if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3417 $v_extract = true;
3418 }
3419 if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3420 $j_start = $j+1;
3421 }
3422
3423 if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3424 break;
3425 }
3426 }
3427 }
3428
3429
3430 else {
3431 $v_extract = true;
3432 }
3433
3434
3435 if ( ($v_extract)
3436 && ( ($v_header['compression'] != 8)
3437 && ($v_header['compression'] != 0))) {
3438 $v_header['status'] = 'unsupported_compression';
3439
3440
3441 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3442 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3443
3444 $this->privSwapBackMagicQuotes();
3445
3446 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3447 "Filename '".$v_header['stored_filename']."' is "
3448 ."compressed by an unsupported compression "
3449 ."method (".$v_header['compression'].") ");
3450
3451 return PclZip::errorCode();
3452 }
3453 }
3454
3455
3456 if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3457 $v_header['status'] = 'unsupported_encryption';
3458
3459
3460 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3461 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3462
3463 $this->privSwapBackMagicQuotes();
3464
3465 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3466 "Unsupported encryption for "
3467 ." filename '".$v_header['stored_filename']
3468 ."'");
3469
3470 return PclZip::errorCode();
3471 }
3472 }
3473
3474
3475 if (($v_extract) && ($v_header['status'] != 'ok')) {
3476 $v_result = $this->privConvertHeader2FileInfo($v_header,
3477 $p_file_list[$v_nb_extracted++]);
3478 if ($v_result != 1) {
3479 $this->privCloseFd();
3480 $this->privSwapBackMagicQuotes();
3481 return $v_result;
3482 }
3483
3484 $v_extract = false;
3485 }
3486
3487
3488 if ($v_extract)
3489 {
3490
3491
3492 @rewind($this->zip_fd);
3493 if (@fseek($this->zip_fd, $v_header['offset']))
3494 {
3495
3496 $this->privCloseFd();
3497
3498 $this->privSwapBackMagicQuotes();
3499
3500
3501 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3502
3503
3504 return PclZip::errorCode();
3505 }
3506
3507
3508 if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3509
3510 $v_string = '';
3511
3512
3513 $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3514 if ($v_result1 < 1) {
3515 $this->privCloseFd();
3516 $this->privSwapBackMagicQuotes();
3517 return $v_result1;
3518 }
3519
3520
3521 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3522 {
3523
3524 $this->privCloseFd();
3525 $this->privSwapBackMagicQuotes();
3526
3527 return $v_result;
3528 }
3529
3530
3531 $p_file_list[$v_nb_extracted]['content'] = $v_string;
3532
3533
3534 $v_nb_extracted++;
3535
3536
3537 if ($v_result1 == 2) {
3538 break;
3539 }
3540 }
3541
3542 elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3543 && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3544
3545 $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3546 if ($v_result1 < 1) {
3547 $this->privCloseFd();
3548 $this->privSwapBackMagicQuotes();
3549 return $v_result1;
3550 }
3551
3552
3553 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3554 $this->privCloseFd();
3555 $this->privSwapBackMagicQuotes();
3556 return $v_result;
3557 }
3558
3559
3560 if ($v_result1 == 2) {
3561 break;
3562 }
3563 }
3564
3565 else {
3566
3567 $v_result1 = $this->privExtractFile($v_header,
3568 $p_path, $p_remove_path,
3569 $p_remove_all_path,
3570 $p_options);
3571 if ($v_result1 < 1) {
3572 $this->privCloseFd();
3573 $this->privSwapBackMagicQuotes();
3574 return $v_result1;
3575 }
3576
3577
3578 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3579 {
3580
3581 $this->privCloseFd();
3582 $this->privSwapBackMagicQuotes();
3583
3584 return $v_result;
3585 }
3586
3587
3588 if ($v_result1 == 2) {
3589 break;
3590 }
3591 }
3592 }
3593 }
3594
3595
3596 $this->privCloseFd();
3597 $this->privSwapBackMagicQuotes();
3598
3599
3600 return $v_result;
3601 }
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613 function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3614 {
3615 $v_result=1;
3616
3617
3618 if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3619 {
3620
3621 return $v_result;
3622 }
3623
3624
3625
3626 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3627
3628 }
3629
3630
3631 if ($p_remove_all_path == true) {
3632
3633 if (($p_entry['external']&0x00000010)==0x00000010) {
3634
3635 $p_entry['status'] = "filtered";
3636
3637 return $v_result;
3638 }
3639
3640
3641 $p_entry['filename'] = basename($p_entry['filename']);
3642 }
3643
3644
3645 else if ($p_remove_path != "")
3646 {
3647 if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3648 {
3649
3650
3651 $p_entry['status'] = "filtered";
3652
3653
3654 return $v_result;
3655 }
3656
3657 $p_remove_path_size = strlen($p_remove_path);
3658 if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3659 {
3660
3661
3662 $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3663
3664 }
3665 }
3666
3667
3668 if ($p_path != '') {
3669 $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3670 }
3671
3672
3673 if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3674 $v_inclusion
3675 = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3676 $p_entry['filename']);
3677 if ($v_inclusion == 0) {
3678
3679 PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3680 "Filename '".$p_entry['filename']."' is "
3681 ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3682
3683 return PclZip::errorCode();
3684 }
3685 }
3686
3687
3688 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3689
3690
3691 $v_local_header = array();
3692 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3693
3694
3695
3696
3697 $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3698 if ($v_result == 0) {
3699
3700 $p_entry['status'] = "skipped";
3701 $v_result = 1;
3702 }
3703
3704
3705 if ($v_result == 2) {
3706
3707 $p_entry['status'] = "aborted";
3708 $v_result = PCLZIP_ERR_USER_ABORTED;
3709 }
3710
3711
3712
3713 $p_entry['filename'] = $v_local_header['filename'];
3714 }
3715
3716
3717
3718 if ($p_entry['status'] == 'ok') {
3719
3720
3721 if (file_exists($p_entry['filename']))
3722 {
3723
3724
3725 if (is_dir($p_entry['filename']))
3726 {
3727
3728
3729 $p_entry['status'] = "already_a_directory";
3730
3731
3732
3733
3734 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3735 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3736
3737 PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3738 "Filename '".$p_entry['filename']."' is "
3739 ."already used by an existing directory");
3740
3741 return PclZip::errorCode();
3742 }
3743 }
3744
3745 else if (!is_writeable($p_entry['filename']))
3746 {
3747
3748
3749 $p_entry['status'] = "write_protected";
3750
3751
3752
3753
3754 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3755 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3756
3757 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3758 "Filename '".$p_entry['filename']."' exists "
3759 ."and is write protected");
3760
3761 return PclZip::errorCode();
3762 }
3763 }
3764
3765
3766 else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3767 {
3768
3769 if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
3770 && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3771 }
3772 else {
3773 $p_entry['status'] = "newer_exist";
3774
3775
3776
3777
3778 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3779 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3780
3781 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3782 "Newer version of '".$p_entry['filename']."' exists "
3783 ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3784
3785 return PclZip::errorCode();
3786 }
3787 }
3788 }
3789 else {
3790 }
3791 }
3792
3793
3794 else {
3795 if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3796 $v_dir_to_check = $p_entry['filename'];
3797 else if (!strstr($p_entry['filename'], "/"))
3798 $v_dir_to_check = "";
3799 else
3800 $v_dir_to_check = dirname($p_entry['filename']);
3801
3802 if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3803
3804
3805 $p_entry['status'] = "path_creation_fail";
3806
3807
3808
3809 $v_result = 1;
3810 }
3811 }
3812 }
3813
3814
3815 if ($p_entry['status'] == 'ok') {
3816
3817
3818 if (!(($p_entry['external']&0x00000010)==0x00000010))
3819 {
3820
3821 if ($p_entry['compression'] == 0) {
3822
3823
3824 if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3825 {
3826
3827
3828 $p_entry['status'] = "write_error";
3829
3830
3831 return $v_result;
3832 }
3833
3834
3835
3836 $v_size = $p_entry['compressed_size'];
3837 while ($v_size != 0)
3838 {
3839 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3840 $v_buffer = @fread($this->zip_fd, $v_read_size);
3841
3842
3843
3844
3845 @fwrite($v_dest_file, $v_buffer, $v_read_size);
3846 $v_size -= $v_read_size;
3847 }
3848
3849
3850 fclose($v_dest_file);
3851
3852
3853 touch($p_entry['filename'], $p_entry['mtime']);
3854
3855
3856 }
3857 else {
3858
3859
3860 if (($p_entry['flag'] & 1) == 1) {
3861 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
3862 return PclZip::errorCode();
3863 }
3864
3865
3866
3867 if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
3868 && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
3869 || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
3870 && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
3871 $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3872 if ($v_result < PCLZIP_ERR_NO_ERROR) {
3873 return $v_result;
3874 }
3875 }
3876
3877
3878 else {
3879
3880
3881
3882 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3883
3884
3885 $v_file_content = @gzinflate($v_buffer);
3886 unset($v_buffer);
3887 if ($v_file_content === FALSE) {
3888
3889
3890
3891 $p_entry['status'] = "error";
3892
3893 return $v_result;
3894 }
3895
3896
3897 if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3898
3899
3900 $p_entry['status'] = "write_error";
3901
3902 return $v_result;
3903 }
3904
3905
3906 @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3907 unset($v_file_content);
3908
3909
3910 @fclose($v_dest_file);
3911
3912 }
3913
3914
3915 @touch($p_entry['filename'], $p_entry['mtime']);
3916 }
3917
3918
3919 if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3920
3921
3922 @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
3923 }
3924
3925 }
3926 }
3927
3928
3929 if ($p_entry['status'] == "aborted") {
3930 $p_entry['status'] = "skipped";
3931 }
3932
3933
3934 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3935
3936
3937 $v_local_header = array();
3938 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3939
3940
3941
3942
3943 $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3944
3945
3946 if ($v_result == 2) {
3947 $v_result = PCLZIP_ERR_USER_ABORTED;
3948 }
3949 }
3950
3951
3952 return $v_result;
3953 }
3954
3955
3956
3957
3958
3959
3960
3961
3962 function privExtractFileUsingTempFile(&$p_entry, &$p_options)
3963 {
3964 $v_result=1;
3965
3966
3967 $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
3968 if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3969 fclose($v_file);
3970 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
3971 return PclZip::errorCode();
3972 }
3973
3974
3975
3976 $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
3977 @fwrite($v_dest_file, $v_binary_data, 10);
3978
3979
3980 $v_size = $p_entry['compressed_size'];
3981 while ($v_size != 0)
3982 {
3983 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3984 $v_buffer = @fread($this->zip_fd, $v_read_size);
3985
3986 @fwrite($v_dest_file, $v_buffer, $v_read_size);
3987 $v_size -= $v_read_size;
3988 }
3989
3990
3991 $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
3992 @fwrite($v_dest_file, $v_binary_data, 8);
3993
3994
3995 @fclose($v_dest_file);
3996
3997
3998 if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3999 $p_entry['status'] = "write_error";
4000 return $v_result;
4001 }
4002
4003
4004 if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
4005 @fclose($v_dest_file);
4006 $p_entry['status'] = "read_error";
4007 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
4008 return PclZip::errorCode();
4009 }
4010
4011
4012
4013 $v_size = $p_entry['size'];
4014 while ($v_size != 0) {
4015 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4016 $v_buffer = @gzread($v_src_file, $v_read_size);
4017
4018 @fwrite($v_dest_file, $v_buffer, $v_read_size);
4019 $v_size -= $v_read_size;
4020 }
4021 @fclose($v_dest_file);
4022 @gzclose($v_src_file);
4023
4024
4025 @unlink($v_gzip_temp_name);
4026
4027
4028 return $v_result;
4029 }
4030
4031
4032
4033
4034
4035
4036
4037
4038 function privExtractFileInOutput(&$p_entry, &$p_options)
4039 {
4040 $v_result=1;
4041
4042
4043 if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
4044 return $v_result;
4045 }
4046
4047
4048
4049 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4050
4051 }
4052
4053
4054 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4055
4056
4057 $v_local_header = array();
4058 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4059
4060
4061
4062
4063
4064 $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4065 if ($v_result == 0) {
4066
4067 $p_entry['status'] = "skipped";
4068 $v_result = 1;
4069 }
4070
4071
4072 if ($v_result == 2) {
4073
4074 $p_entry['status'] = "aborted";
4075 $v_result = PCLZIP_ERR_USER_ABORTED;
4076 }
4077
4078
4079
4080 $p_entry['filename'] = $v_local_header['filename'];
4081 }
4082
4083
4084
4085
4086 if ($p_entry['status'] == 'ok') {
4087
4088
4089 if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4090
4091 if ($p_entry['compressed_size'] == $p_entry['size']) {
4092
4093
4094 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4095
4096
4097 echo $v_buffer;
4098 unset($v_buffer);
4099 }
4100 else {
4101
4102
4103 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4104
4105
4106 $v_file_content = gzinflate($v_buffer);
4107 unset($v_buffer);
4108
4109
4110 echo $v_file_content;
4111 unset($v_file_content);
4112 }
4113 }
4114 }
4115
4116
4117 if ($p_entry['status'] == "aborted") {
4118 $p_entry['status'] = "skipped";
4119 }
4120
4121
4122 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4123
4124
4125 $v_local_header = array();
4126 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4127
4128
4129
4130
4131 $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4132
4133
4134 if ($v_result == 2) {
4135 $v_result = PCLZIP_ERR_USER_ABORTED;
4136 }
4137 }
4138
4139 return $v_result;
4140 }
4141
4142
4143
4144
4145
4146
4147
4148
4149 function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
4150 {
4151 $v_result=1;
4152
4153
4154 $v_header = array();
4155 if (($v_result = $this->privReadFileHeader($v_header)) != 1)
4156 {
4157
4158 return $v_result;
4159 }
4160
4161
4162
4163 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4164
4165 }
4166
4167
4168 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4169
4170
4171 $v_local_header = array();
4172 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4173
4174
4175
4176
4177 $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4178 if ($v_result == 0) {
4179
4180 $p_entry['status'] = "skipped";
4181 $v_result = 1;
4182 }
4183
4184
4185 if ($v_result == 2) {
4186
4187 $p_entry['status'] = "aborted";
4188 $v_result = PCLZIP_ERR_USER_ABORTED;
4189 }
4190
4191
4192
4193 $p_entry['filename'] = $v_local_header['filename'];
4194 }
4195
4196
4197
4198 if ($p_entry['status'] == 'ok') {
4199
4200
4201 if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4202
4203
4204 if ($p_entry['compression'] == 0) {
4205
4206
4207 $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4208 }
4209 else {
4210
4211
4212 $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4213
4214
4215 if (($p_string = @gzinflate($v_data)) === FALSE) {
4216
4217 }
4218 }
4219
4220
4221 }
4222 else {
4223
4224 }
4225
4226 }
4227
4228
4229 if ($p_entry['status'] == "aborted") {
4230 $p_entry['status'] = "skipped";
4231 }
4232
4233
4234 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4235
4236
4237 $v_local_header = array();
4238 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4239
4240
4241 $v_local_header['content'] = $p_string;
4242 $p_string = '';
4243
4244
4245
4246
4247 $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4248
4249
4250 $p_string = $v_local_header['content'];
4251 unset($v_local_header['content']);
4252
4253
4254 if ($v_result == 2) {
4255 $v_result = PCLZIP_ERR_USER_ABORTED;
4256 }
4257 }
4258
4259
4260 return $v_result;
4261 }
4262
4263
4264
4265
4266
4267
4268
4269
4270 function privReadFileHeader(&$p_header)
4271 {
4272 $v_result=1;
4273
4274
4275 $v_binary_data = @fread($this->zip_fd, 4);
4276 $v_data = unpack('Vid', $v_binary_data);
4277
4278
4279 if ($v_data['id'] != 0x04034b50)
4280 {
4281
4282
4283 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4284
4285
4286 return PclZip::errorCode();
4287 }
4288
4289
4290 $v_binary_data = fread($this->zip_fd, 26);
4291
4292
4293 if (strlen($v_binary_data) != 26)
4294 {
4295 $p_header['filename'] = "";
4296 $p_header['status'] = "invalid_header";
4297
4298
4299 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4300
4301
4302 return PclZip::errorCode();
4303 }
4304
4305
4306 $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4307
4308
4309 $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4310
4311
4312 if ($v_data['extra_len'] != 0) {
4313 $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4314 }
4315 else {
4316 $p_header['extra'] = '';
4317 }
4318
4319
4320 $p_header['version_extracted'] = $v_data['version'];
4321 $p_header['compression'] = $v_data['compression'];
4322 $p_header['size'] = $v_data['size'];
4323 $p_header['compressed_size'] = $v_data['compressed_size'];
4324 $p_header['crc'] = $v_data['crc'];
4325 $p_header['flag'] = $v_data['flag'];
4326 $p_header['filename_len'] = $v_data['filename_len'];
4327
4328
4329 $p_header['mdate'] = $v_data['mdate'];
4330 $p_header['mtime'] = $v_data['mtime'];
4331 if ($p_header['mdate'] && $p_header['mtime'])
4332 {
4333
4334 $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4335 $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4336 $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4337
4338
4339 $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4340 $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4341 $v_day = $p_header['mdate'] & 0x001F;
4342
4343
4344 $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4345
4346 }
4347 else
4348 {
4349 $p_header['mtime'] = time();
4350 }
4351
4352
4353
4354
4355
4356
4357 $p_header['stored_filename'] = $p_header['filename'];
4358
4359
4360 $p_header['status'] = "ok";
4361
4362
4363 return $v_result;
4364 }
4365
4366
4367
4368
4369
4370
4371
4372
4373 function privReadCentralFileHeader(&$p_header)
4374 {
4375 $v_result=1;
4376
4377
4378 $v_binary_data = @fread($this->zip_fd, 4);
4379 $v_data = unpack('Vid', $v_binary_data);
4380
4381
4382 if ($v_data['id'] != 0x02014b50)
4383 {
4384
4385
4386 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4387
4388
4389 return PclZip::errorCode();
4390 }
4391
4392
4393 $v_binary_data = fread($this->zip_fd, 42);
4394
4395
4396 if (strlen($v_binary_data) != 42)
4397 {
4398 $p_header['filename'] = "";
4399 $p_header['status'] = "invalid_header";
4400
4401
4402 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4403
4404
4405 return PclZip::errorCode();
4406 }
4407
4408
4409 $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);
4410
4411
4412 if ($p_header['filename_len'] != 0)
4413 $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4414 else
4415 $p_header['filename'] = '';
4416
4417
4418 if ($p_header['extra_len'] != 0)
4419 $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4420 else
4421 $p_header['extra'] = '';
4422
4423
4424 if ($p_header['comment_len'] != 0)
4425 $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4426 else
4427 $p_header['comment'] = '';
4428
4429
4430
4431
4432
4433
4434 if (1)
4435 {
4436
4437 $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4438 $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4439 $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4440
4441
4442 $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4443 $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4444 $v_day = $p_header['mdate'] & 0x001F;
4445
4446
4447 $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4448
4449 }
4450 else
4451 {
4452 $p_header['mtime'] = time();
4453 }
4454
4455
4456 $p_header['stored_filename'] = $p_header['filename'];
4457
4458
4459 $p_header['status'] = 'ok';
4460
4461
4462 if (substr($p_header['filename'], -1) == '/') {
4463
4464 $p_header['external'] = 0x00000010;
4465 }
4466
4467
4468
4469 return $v_result;
4470 }
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481 function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4482 {
4483 $v_result=1;
4484
4485
4486
4487 if ($p_local_header['filename'] != $p_central_header['filename']) {
4488 }
4489 if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4490 }
4491 if ($p_local_header['flag'] != $p_central_header['flag']) {
4492 }
4493 if ($p_local_header['compression'] != $p_central_header['compression']) {
4494 }
4495 if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4496 }
4497 if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4498 }
4499
4500
4501 if (($p_local_header['flag'] & 8) == 8) {
4502 $p_local_header['size'] = $p_central_header['size'];
4503 $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4504 $p_local_header['crc'] = $p_central_header['crc'];
4505 }
4506
4507
4508 return $v_result;
4509 }
4510
4511
4512
4513
4514
4515
4516
4517
4518 function privReadEndCentralDir(&$p_central_dir)
4519 {
4520 $v_result=1;
4521
4522
4523 $v_size = filesize($this->zipname);
4524 @fseek($this->zip_fd, $v_size);
4525 if (@ftell($this->zip_fd) != $v_size)
4526 {
4527
4528 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4529
4530
4531 return PclZip::errorCode();
4532 }
4533
4534
4535
4536 $v_found = 0;
4537 if ($v_size > 26) {
4538 @fseek($this->zip_fd, $v_size-22);
4539 if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4540 {
4541
4542 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4543
4544
4545 return PclZip::errorCode();
4546 }
4547
4548
4549 $v_binary_data = @fread($this->zip_fd, 4);
4550 $v_data = @unpack('Vid', $v_binary_data);
4551
4552
4553 if ($v_data['id'] == 0x06054b50) {
4554 $v_found = 1;
4555 }
4556
4557 $v_pos = ftell($this->zip_fd);
4558 }
4559
4560
4561 if (!$v_found) {
4562 $v_maximum_size = 65557;
4563 if ($v_maximum_size > $v_size)
4564 $v_maximum_size = $v_size;
4565 @fseek($this->zip_fd, $v_size-$v_maximum_size);
4566 if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4567 {
4568
4569 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4570
4571
4572 return PclZip::errorCode();
4573 }
4574
4575
4576 $v_pos = ftell($this->zip_fd);
4577 $v_bytes = 0x00000000;
4578 while ($v_pos < $v_size)
4579 {
4580
4581 $v_byte = @fread($this->zip_fd, 1);
4582
4583
4584
4585
4586
4587 $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
4588
4589
4590 if ($v_bytes == 0x504b0506)
4591 {
4592 $v_pos++;
4593 break;
4594 }
4595
4596 $v_pos++;
4597 }
4598
4599
4600 if ($v_pos == $v_size)
4601 {
4602
4603
4604 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4605
4606
4607 return PclZip::errorCode();
4608 }
4609 }
4610
4611
4612 $v_binary_data = fread($this->zip_fd, 18);
4613
4614
4615 if (strlen($v_binary_data) != 18)
4616 {
4617
4618
4619 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4620
4621
4622 return PclZip::errorCode();
4623 }
4624
4625
4626 $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4627
4628
4629 if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
4630
4631
4632
4633
4634
4635 if (0) {
4636
4637 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4638 'The central dir is not at the end of the archive.'
4639 .' Some trailing bytes exists after the archive.');
4640
4641
4642 return PclZip::errorCode();
4643 }
4644 }
4645
4646
4647 if ($v_data['comment_size'] != 0) {
4648 $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4649 }
4650 else
4651 $p_central_dir['comment'] = '';
4652
4653 $p_central_dir['entries'] = $v_data['entries'];
4654 $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4655 $p_central_dir['offset'] = $v_data['offset'];
4656 $p_central_dir['size'] = $v_data['size'];
4657 $p_central_dir['disk'] = $v_data['disk'];
4658 $p_central_dir['disk_start'] = $v_data['disk_start'];
4659
4660
4661
4662
4663
4664
4665 return $v_result;
4666 }
4667
4668
4669
4670
4671
4672
4673
4674
4675 function privDeleteByRule(&$p_result_list, &$p_options)
4676 {
4677 $v_result=1;
4678 $v_list_detail = array();
4679
4680
4681 if (($v_result=$this->privOpenFd('rb')) != 1)
4682 {
4683
4684 return $v_result;
4685 }
4686
4687
4688 $v_central_dir = array();
4689 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4690 {
4691 $this->privCloseFd();
4692 return $v_result;
4693 }
4694
4695
4696 @rewind($this->zip_fd);
4697
4698
4699
4700 $v_pos_entry = $v_central_dir['offset'];
4701 @rewind($this->zip_fd);
4702 if (@fseek(