Issues (67)

src/Base/Archive/InfozipZipper.php (2 issues)

Labels
Severity
1
<?php
2
3
/*
4
 * Pickle
5
 *
6
 *
7
 * @license
8
 *
9
 * New BSD License
10
 *
11
 * Copyright © 2015-2015, Pickle community. All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *     * Redistributions of source code must retain the above copyright
16
 *       notice, this list of conditions and the following disclaimer.
17
 *     * Redistributions in binary form must reproduce the above copyright
18
 *       notice, this list of conditions and the following disclaimer in the
19
 *       documentation and/or other materials provided with the distribution.
20
 *     * Neither the name of the Hoa nor the names of its contributors may be
21
 *       used to endorse or promote products derived from this software without
22
 *       specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 */
36
37
namespace Pickle\Base\Archive;
38
39
use Pickle\Base\Interfaces;
40
use Pickle\Base\Util\FileOps;
41
use RuntimeException;
42
use Throwable;
43
44
class InfozipZipper extends Infozip implements Interfaces\Archive\Zipper
45
{
46
    use FileOps;
47
48
    /**
49
     * {@inheritDoc}
50
     *
51
     * @see \Pickle\Base\Interfaces\Archive\Zipper::__construct()
52
     */
53
    public function __construct(string $path, int $flags)
54
    {
55
        parent::__construct($path);
56
        switch ($flags) {
57
            case self::FLAG_OPEN:
58
                $this->checkExisting();
59
                break;
60
            case self::FLAG_CREATE:
61
                $this->create(false);
62
                break;
63
            case self::FLAG_CREATE_OVERWRITE:
64
                $this->create(true);
65
                break;
66
            default:
67
                throw new RuntimeException('Invalid value of $flags in ' . __METHOD__);
68
        }
69
    }
70
71
    /**
72
     * {@inheritDoc}
73
     *
74
     * @see \Pickle\Base\Interfaces\Archive\Zipper::__destruct()
75
     */
76
    public function __destruct()
77
    {
78
        $this->cleanup();
79
    }
80
81
    /**
82
     * {@inheritDoc}
83
     *
84
     * @see \Pickle\Base\Interfaces\Archive\Zipper::addFromString($localname, $contents)
85
     */
86
    public function addFromString(string $localname, string $contents): void
87
    {
88
        $localname = ltrim(str_replace(DIRECTORY_SEPARATOR, '/', $localname), '/');
89
        $this->createTempDir();
90
        $tempDir = $this->getTempDir();
91
        $dirname = dirname($localname);
92
        if ($dirname !== '' && $dirname !== '.') {
93
            if (mkdir($tempDir . '/' . $dirname, 0777, true) !== true) {
94
                throw new RuntimeException('Failed to create a temporary directory');
95
            }
96
        }
97
        if (file_put_contents($tempDir . '/' . $localname, $contents) === false) {
98
            throw new RuntimeException('Failed to write a temporary file');
99
        }
100
        $originalCWD = getcwd();
101
        if (chdir($tempDir) !== true) {
102
            throw new RuntimeException("Failed to enter directory {$tempDir}");
103
        }
104
        try {
105
            $this->run('zip', [
106
                escapeshellarg($this->path),
107
                escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $localname)),
108
            ]);
109
        } finally {
110
            chdir($originalCWD);
111
        }
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     *
117
     * @see \Pickle\Base\Interfaces\Archive\Zipper::addFileWithoutPath()
118
     */
119
    public function addFileWithoutPath(string $path): void
120
    {
121
        $path = str_replace('/', DIRECTORY_SEPARATOR, $path);
122
        if (!is_file($path)) {
123
            throw new RuntimeException("Failed to find the file {$path}");
124
        }
125
        if (!is_readable($path)) {
126
            throw new RuntimeException("The file {$path} is not readable");
127
        }
128
        $this->run('zip', [
129
            '-j',
130
            escapeshellarg($this->path),
131
            escapeshellarg($path),
132
        ]);
133
    }
134
135
    private function create(bool $overwrite): void
136
    {
137
        if (file_exists($this->path)) {
138
            if ($overwrite === false) {
139
                throw new RuntimeException("The ZIP archive {$this->path} already exists");
140
            }
141
            if (unlink($this->path) === false) {
142
                throw new RuntimeException("Failed to overwrite the ZIP archive {$this->path}");
143
            }
144
        }
145
        $this->run([
0 ignored issues
show
The call to Pickle\Base\Archive\Infozip::run() has too few arguments starting with args. ( Ignorable by Annotation )

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

145
        $this->/** @scrutinizer ignore-call */ 
146
               run([

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
array('-j1', escapeshell...capeshellarg(__FILE__)) of type array<integer,string> is incompatible with the type string expected by parameter $command of Pickle\Base\Archive\Infozip::run(). ( Ignorable by Annotation )

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

145
        $this->run(/** @scrutinizer ignore-type */ [
Loading history...
146
            '-j1',
147
            escapeshellarg($this->path),
148
            escapeshellarg(__FILE__),
149
        ]);
150
        try {
151
            $this->run([
152
                '-d',
153
                escapeshellarg($this->path),
154
                escapeshellarg(basename(__FILE__)),
155
            ]);
156
        } catch (Throwable $x) {
157
            unlink($this->path);
158
            throw $x;
159
        }
160
    }
161
}
162
163
/* vim: set tabstop=4 shiftwidth=4 expandtab: fdm=marker */
164