diff --git a/src/Model/ZipEntry.php b/src/Model/ZipEntry.php
index 5194fc0..dd3015e 100644
--- a/src/Model/ZipEntry.php
+++ b/src/Model/ZipEntry.php
@@ -1447,7 +1447,7 @@ public function getUnixMode()
             return $mode;
         }
 
-        return $this->isDirectory ? 040755 : 0100644;
+        return $this->isDirectory && !$this->isUnixSymlink() ? 040755 : 0100644;
     }
 
     /**
diff --git a/src/Util/FilesUtil.php b/src/Util/FilesUtil.php
index 3e64614..cf7a4d4 100644
--- a/src/Util/FilesUtil.php
+++ b/src/Util/FilesUtil.php
@@ -45,7 +45,7 @@ public static function removeDir($dir)
 
         /** @var \SplFileInfo $fileInfo */
         foreach ($files as $fileInfo) {
-            $function = ($fileInfo->isDir() ? 'rmdir' : 'unlink');
+            $function = ($fileInfo->isDir() && !$fileInfo->isLink() ? 'rmdir' : 'unlink');
             $function($fileInfo->getPathname());
         }
         @rmdir($dir);
diff --git a/src/ZipFile.php b/src/ZipFile.php
index 384c03f..e3ebab0 100644
--- a/src/ZipFile.php
+++ b/src/ZipFile.php
@@ -688,7 +688,7 @@ public function addSplFile(\SplFileInfo $file, $entryName = null, array $options
         }
 
         $entryName = $this->normalizeEntryName($entryName);
-        $entryName = $file->isDir() ? rtrim($entryName, '/\\') . '/' : $entryName;
+        $entryName = $file->isDir() && !$file->isLink() ? rtrim($entryName, '/\\') . '/' : $entryName;
 
         $zipEntry = new ZipEntry($entryName);
         $zipEntry->setCreatedOS(ZipPlatform::OS_UNIX);
@@ -706,6 +706,7 @@ public function addSplFile(\SplFileInfo $file, $entryName = null, array $options
             $zipEntry->setCompressedSize($lengthLinkTarget);
             $zipEntry->setCrc(crc32($linkTarget));
             $filePerms |= UnixStat::UNX_IFLNK;
+            $filePerms &= ~UnixStat::UNX_IFDIR;
 
             $zipData = new ZipNewData($zipEntry, $linkTarget);
         } elseif ($file->isFile()) {
diff --git a/tests/SymlinkTest.php b/tests/SymlinkTest.php
index f7d3b7a..bf4e461 100644
--- a/tests/SymlinkTest.php
+++ b/tests/SymlinkTest.php
@@ -14,6 +14,8 @@
  */
 final class SymlinkTest extends ZipTestCase
 {
+
+
     /**
      * @dataProvider provideAllowSymlink
      *
@@ -67,6 +69,66 @@ public function testSymlink($allowSymlink)
         }
     }
 
+    /**
+     * @dataProvider provideAllowSymlink
+     *
+     * @param bool $allowSymlink
+     *
+     * @throws \Exception
+     */
+    public function testSymlinkedDirectory($allowSymlink)
+    {
+        if (self::skipTestForWindows()) {
+            return;
+        }
+
+        if (!is_dir($this->outputDirname)) {
+            self::assertTrue(mkdir($this->outputDirname, 0755, true));
+        }
+
+        $dirToBeLinked = $this->outputDirname . '/dir-to-be-linked';
+        self::assertTrue(mkdir($dirToBeLinked, 0755, true));
+
+        $contentsFile = random_bytes(100);
+        $filePath = $dirToBeLinked . '/file.bin';
+        self::assertNotFalse(file_put_contents($filePath, $contentsFile));
+        $symlinkPath = $this->outputDirname . '/symlink.dir';
+        $symlinkTarget = basename($dirToBeLinked);
+        self::assertTrue(symlink($symlinkTarget, $symlinkPath));
+
+        $finder = (new Finder())->in($this->outputDirname);
+        $zipFile = new ZipFile();
+        $zipFile->addFromFinder($finder);
+        $zipFile->saveAsFile($this->outputFilename);
+        $zipFile->close();
+
+        self::assertCorrectZipArchive($this->outputFilename);
+
+        FilesUtil::removeDir($this->outputDirname);
+        self::assertFalse(is_dir($this->outputDirname));
+        self::assertTrue(mkdir($this->outputDirname, 0755, true));
+
+        $zipFile->openFile($this->outputFilename);
+        $zipFile->extractTo($this->outputDirname, null, [
+            ZipOptions::EXTRACT_SYMLINKS => $allowSymlink,
+        ]);
+        $zipFile->close();
+
+        $splFileInfo = new \SplFileInfo($symlinkPath);
+
+        if ($allowSymlink) {
+            self::assertTrue($splFileInfo->isLink());
+            self::assertSame($splFileInfo->getLinkTarget(), $symlinkTarget);
+            $linkedFilename = $symlinkPath."/".basename($filePath);
+            self::assertFileExists($linkedFilename);
+            $linkedFileContents = file_get_contents($linkedFilename);
+            self::assertEquals($contentsFile, $linkedFileContents);
+        } else {
+            self::assertFalse($splFileInfo->isLink());
+            self::assertStringEqualsFile($symlinkPath, $symlinkTarget);
+        }
+    }
+
     /**
      * @return \Generator
      */