Browse Source

Fix #22 Adding links to files, not open handles

Ne-Lexa 7 years ago
parent
commit
c863c18869

+ 0 - 3
src/PhpZip/Model/Entry/ZipNewEntry.php

@@ -6,9 +6,6 @@ use PhpZip\Exception\InvalidArgumentException;
 use PhpZip\ZipFileInterface;
 
 /**
- * Abstract class for new zip entry.
- *
- * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
  * @author Ne-Lexa alexey@nelexa.ru
  * @license MIT
  */

+ 53 - 0
src/PhpZip/Model/Entry/ZipNewFileEntry.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace PhpZip\Model\Entry;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\RuntimeException;
+use PhpZip\Exception\ZipException;
+
+/**
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipNewFileEntry extends ZipAbstractEntry
+{
+    /**
+     * @var string Filename
+     */
+    protected $file;
+
+    /**
+     * ZipNewEntry constructor.
+     * @param string $file
+     * @throws ZipException
+     */
+    public function __construct($file)
+    {
+        parent::__construct();
+        if ($file === null){
+            throw new InvalidArgumentException("file is null");
+        }
+        $file = (string)$file;
+        if (!is_file($file)){
+            throw new ZipException("File $file does not exist.");
+        }
+        if (!is_readable($file)){
+            throw new ZipException("The '$file' file could not be read. Check permissions.");
+        }
+        $this->file = $file;
+    }
+
+    /**
+     * Returns an string content of the given entry.
+     *
+     * @return null|string
+     */
+    public function getEntryContent()
+    {
+        if (!is_file($this->file)){
+            throw new RuntimeException("File {$this->file} does not exist.");
+        }
+        return file_get_contents($this->file);
+    }
+}

+ 17 - 11
src/PhpZip/ZipFile.php

@@ -7,6 +7,7 @@ use PhpZip\Exception\ZipEntryNotFoundException;
 use PhpZip\Exception\ZipException;
 use PhpZip\Exception\ZipUnsupportMethodException;
 use PhpZip\Model\Entry\ZipNewEntry;
+use PhpZip\Model\Entry\ZipNewFileEntry;
 use PhpZip\Model\ZipEntry;
 use PhpZip\Model\ZipEntryMatcher;
 use PhpZip\Model\ZipInfo;
@@ -414,12 +415,7 @@ class ZipFile implements ZipFileInterface
      */
     public function addFile($filename, $localName = null, $compressionMethod = null)
     {
-        if ($filename === null) {
-            throw new InvalidArgumentException("Filename is null");
-        }
-        if (!is_file($filename)) {
-            throw new ZipException("File $filename is not exists");
-        }
+        $entry = new ZipNewFileEntry($filename);
 
         if ($compressionMethod === null) {
             if (function_exists('mime_content_type')) {
@@ -442,14 +438,24 @@ class ZipFile implements ZipFileInterface
             throw new ZipUnsupportMethodException('Unsupported compression method ' . $compressionMethod);
         }
 
-        if (!($handle = @fopen($filename, 'rb'))) {
-            throw new ZipException('File ' . $filename . ' can not open.');
-        }
         if ($localName === null) {
             $localName = basename($filename);
         }
-        $this->addFromStream($handle, $localName, $compressionMethod);
-        $this->zipModel->getEntry($localName)->setTime(filemtime($filename));
+        $localName = ltrim((string)$localName, "\\/");
+        if (strlen($localName) === 0) {
+            throw new InvalidArgumentException("Empty entry name");
+        }
+
+        $stat = stat($filename);
+        $mode = sprintf('%o', $stat['mode']);
+        $externalAttributes = (octdec($mode) & 0xffff) << 16;
+
+        $entry->setName($localName);
+        $entry->setMethod($compressionMethod);
+        $entry->setTime($stat['mtime']);
+        $entry->setExternalAttributes($externalAttributes);
+
+        $this->zipModel->addEntry($entry);
         return $this;
     }
 

+ 6 - 6
tests/PhpZip/ZipFileTest.php

@@ -34,7 +34,7 @@ class ZipFileTest extends ZipTestCase
     public function testOpenFileCantOpen()
     {
         /** @noinspection PhpComposerExtensionStubsInspection */
-        if (0 === posix_getuid()) {
+        if (posix_getuid() === 0) {
             $this->markTestSkipped('Skip the test for a user with root privileges');
         }
 
@@ -1060,7 +1060,7 @@ class ZipFileTest extends ZipTestCase
     public function testExtractFail3()
     {
         /** @noinspection PhpComposerExtensionStubsInspection */
-        if (0 === posix_getuid()) {
+        if (posix_getuid() === 0) {
             $this->markTestSkipped('Skip the test for a user with root privileges');
         }
 
@@ -1241,7 +1241,7 @@ class ZipFileTest extends ZipTestCase
 
     /**
      * @expectedException \PhpZip\Exception\InvalidArgumentException
-     * @expectedExceptionMessage Filename is null
+     * @expectedExceptionMessage file is null
      * @throws ZipException
      */
     public function testAddFileNullFileName()
@@ -1252,7 +1252,7 @@ class ZipFileTest extends ZipTestCase
 
     /**
      * @expectedException \PhpZip\Exception\ZipException
-     * @expectedExceptionMessage is not exists
+     * @expectedExceptionMessage does not exist
      */
     public function testAddFileCantExists()
     {
@@ -1273,7 +1273,7 @@ class ZipFileTest extends ZipTestCase
 
     /**
      * @expectedException \PhpZip\Exception\ZipException
-     * @expectedExceptionMessage can not open
+     * @expectedExceptionMessage file could not be read
      * @throws ZipException
      */
     public function testAddFileCantOpen()
@@ -1593,7 +1593,7 @@ class ZipFileTest extends ZipTestCase
     public function testSaveAsFileNotWritable()
     {
         /** @noinspection PhpComposerExtensionStubsInspection */
-        if (0 === posix_getuid()) {
+        if (posix_getuid() === 0) {
             $this->markTestSkipped('Skip the test for a user with root privileges');
         }
 

+ 1 - 1
tests/PhpZip/ZipPasswordTest.php

@@ -43,7 +43,7 @@ class ZipPasswordTest extends ZipFileAddDirTest
                 $zipFile[$entryName];
                 $this->fail("Expected Exception has not been raised.");
             } catch (ZipAuthenticationException $ae) {
-                $this->assertNotNull($ae);
+                $this->assertContains('Bad password for entry', $ae->getMessage());
             }
         }