diff --git a/src/Zip Tests/ExtendedTests.cs b/src/Zip Tests/ExtendedTests.cs index 1dde36e..5210638 100644 --- a/src/Zip Tests/ExtendedTests.cs +++ b/src/Zip Tests/ExtendedTests.cs @@ -341,10 +341,32 @@ public void TestZip_IsZipFile_Stream() } } + [TestMethod] + public void ReadZip_DirectoryBitNotSetForFileWithEmojiName() + { + string zipFileToCreate = Path.Combine(TopLevelDir, "ReadZip_DirectoryBitNotSetForFileWithEmojiName.zip"); + string entryName = "Files/\u26BE"; + using (ZipFile zip1 = new ZipFile(Encoding.UTF8)) + { + zip1.AddEntry(entryName, new byte[0]); + ZipEntry entry = zip1[entryName]; + Assert.AreNotEqual(null, entry); + Assert.IsFalse(entry.IsDirectory, + "The IsDirectory property was not set as expected."); + zip1.Save(zipFileToCreate); + } + using (ZipFile zip2 = ZipFile.Read(zipFileToCreate)) + { + ZipEntry entry = zip2[entryName]; + Assert.AreNotEqual(null, entry); + Assert.IsFalse(entry.IsDirectory, + "The IsDirectory property was not set as expected."); + } + } [TestMethod] public void ReadZip_DirectoryBitSetForEmptyDirectories() diff --git a/src/Zip.Shared/Shared.cs b/src/Zip.Shared/Shared.cs index faea421..190e3bf 100644 --- a/src/Zip.Shared/Shared.cs +++ b/src/Zip.Shared/Shared.cs @@ -92,7 +92,7 @@ public static DateTime RoundToEvenSecond(DateTime source) internal static string NormalizePath(string path) { // remove leading single dot slash - if (path.StartsWith(".\\")) path = path.Substring(2); + if (path.StartsWith(".\\", StringComparison.Ordinal)) path = path.Substring(2); // remove intervening dot-slash path = path.Replace("\\.\\", "\\"); @@ -109,7 +109,7 @@ internal static string NormalizePath(string path) private static string SimplifyFwdSlashPath(string path) { - if (path.StartsWith("./")) path = path.Substring(2); + if (path.StartsWith("./", StringComparison.Ordinal)) path = path.Substring(2); path = path.Replace("/./", "/"); // Replace foo/anything/../bar with foo/bar @@ -138,7 +138,7 @@ public static string NormalizePathForUseInZipFile(string pathName) pathName = pathName.Replace('\\', '/'); // trim all leading slashes - while (pathName.StartsWith("/")) pathName = pathName.Substring(1); + while (pathName.StartsWith("/", StringComparison.Ordinal)) pathName = pathName.Substring(1); return SimplifyFwdSlashPath(pathName); } diff --git a/src/Zip.Shared/ZipDirEntry.cs b/src/Zip.Shared/ZipDirEntry.cs index dc4e640..f94e6bf 100644 --- a/src/Zip.Shared/ZipDirEntry.cs +++ b/src/Zip.Shared/ZipDirEntry.cs @@ -288,7 +288,7 @@ internal static ZipEntry ReadDirEntry(ZipFile zf, if (zde.AttributesIndicateDirectory) zde.MarkAsDirectory(); // may append a slash to filename if nec. // workitem 6898 - else if (zde._FileNameInArchive.EndsWith("/")) zde.MarkAsDirectory(); + else if (zde._FileNameInArchive.EndsWith("/", StringComparison.Ordinal)) zde.MarkAsDirectory(); zde._CompressedFileDataSize = zde._CompressedSize; if ((zde._BitField & 0x01) == 0x01) diff --git a/src/Zip.Shared/ZipEntry.Extract.cs b/src/Zip.Shared/ZipEntry.Extract.cs index bdae607..4ee23b2 100644 --- a/src/Zip.Shared/ZipEntry.Extract.cs +++ b/src/Zip.Shared/ZipEntry.Extract.cs @@ -1375,7 +1375,7 @@ bool IsDoneWithOutputToBaseDir(string baseDir, out string outFileName) if (f.IndexOf(':') == 1) f = f.Substring(2); - if (f.StartsWith("/")) + if (f.StartsWith("/", StringComparison.Ordinal)) f = f.Substring(1); f = SharedUtilities.SanitizePath(f); @@ -1388,7 +1388,7 @@ bool IsDoneWithOutputToBaseDir(string baseDir, out string outFileName) outFileName = outFileName.Replace('/', Path.DirectorySeparatorChar); // check if it is a directory - if (IsDirectory || FileName.EndsWith("/")) + if (IsDirectory || FileName.EndsWith("/", StringComparison.Ordinal)) { if (!Directory.Exists(outFileName)) { @@ -1412,7 +1412,7 @@ bool IsDoneWithOutputToBaseDir(string baseDir, out string outFileName) /// bool IsDoneWithOutputToStream() { - return IsDirectory || FileName.EndsWith("/"); + return IsDirectory || FileName.EndsWith("/", StringComparison.Ordinal); } #endregion diff --git a/src/Zip.Shared/ZipEntry.Read.cs b/src/Zip.Shared/ZipEntry.Read.cs index ba61c12..df35faf 100644 --- a/src/Zip.Shared/ZipEntry.Read.cs +++ b/src/Zip.Shared/ZipEntry.Read.cs @@ -141,7 +141,7 @@ private static bool ReadHeader(ZipEntry ze, System.Text.Encoding defaultEncoding ze._FileNameInArchive = ze.AlternateEncoding.GetString(block); // workitem 6898 - if (ze._FileNameInArchive.EndsWith("/")) ze.MarkAsDirectory(); + if (ze._FileNameInArchive.EndsWith("/", StringComparison.Ordinal)) ze.MarkAsDirectory(); bytesRead += ze.ProcessExtraField(ze.ArchiveStream, extraFieldLength); @@ -149,7 +149,7 @@ private static bool ReadHeader(ZipEntry ze, System.Text.Encoding defaultEncoding // workitem 6607 - don't read for directories // actually get the compressed size and CRC if necessary - if (!ze._FileNameInArchive.EndsWith("/") && (ze._BitField & 0x0008) == 0x0008) + if (!ze._IsDirectory && (ze._BitField & 0x0008) == 0x0008) { // This descriptor exists only if bit 3 of the general // purpose bit flag is set (see below). It is byte aligned diff --git a/src/Zip.Shared/ZipEntry.Write.cs b/src/Zip.Shared/ZipEntry.Write.cs index dadb68a..0bb3c03 100644 --- a/src/Zip.Shared/ZipEntry.Write.cs +++ b/src/Zip.Shared/ZipEntry.Write.cs @@ -2461,7 +2461,7 @@ private void CopyThroughWithRecompute(Stream outstream) WriteHeader(outstream, 0); StoreRelativeOffset(); - if (!this.FileName.EndsWith("/")) + if (!this.FileName.EndsWith("/", StringComparison.Ordinal)) { // Not a directory; there is file data. // Seek to the beginning of the entry data in the input stream. diff --git a/src/Zip.Shared/ZipEntry.cs b/src/Zip.Shared/ZipEntry.cs index 8272c9d..4657a6b 100644 --- a/src/Zip.Shared/ZipEntry.cs +++ b/src/Zip.Shared/ZipEntry.cs @@ -2504,7 +2504,7 @@ internal void MarkAsDirectory() { _IsDirectory = true; // workitem 6279 - if (!_FileNameInArchive.EndsWith("/")) + if (!_FileNameInArchive.EndsWith("/", StringComparison.Ordinal)) _FileNameInArchive += "/"; } diff --git a/src/Zip.Shared/ZipFile.Extract.cs b/src/Zip.Shared/ZipFile.Extract.cs index 531c0f3..a6c511a 100644 --- a/src/Zip.Shared/ZipFile.Extract.cs +++ b/src/Zip.Shared/ZipFile.Extract.cs @@ -273,9 +273,9 @@ private void _InternalExtractAll(string path, bool overrideExtractExistingProper foreach (ZipEntry e in _entries.Values) { // check if it is a directory - if ((e.IsDirectory) || (e.FileName.EndsWith("/"))) + if ((e.IsDirectory) || (e.FileName.EndsWith("/", StringComparison.Ordinal))) { - string outputFile = (e.FileName.StartsWith("/")) + string outputFile = (e.FileName.StartsWith("/", StringComparison.Ordinal)) ? Path.Combine(path, e.FileName.Substring(1)) : Path.Combine(path, e.FileName); diff --git a/src/Zip.Shared/ZipFile.Selector.cs b/src/Zip.Shared/ZipFile.Selector.cs index 54e8fc4..ddd26a0 100644 --- a/src/Zip.Shared/ZipFile.Selector.cs +++ b/src/Zip.Shared/ZipFile.Selector.cs @@ -638,7 +638,7 @@ public void UpdateSelectedFiles(String selectionCriteria, private string EnsureendInSlash(string s) { - if (s.EndsWith("\\")) return s; + if (s.EndsWith("\\", StringComparison.Ordinal)) return s; return s + "\\"; } @@ -659,7 +659,7 @@ private void _AddOrUpdateSelectedFiles(String selectionCriteria, } // workitem 9176 - while (directoryOnDisk.EndsWith("\\")) directoryOnDisk = directoryOnDisk.Substring(0, directoryOnDisk.Length - 1); + while (directoryOnDisk.EndsWith("\\", StringComparison.Ordinal)) directoryOnDisk = directoryOnDisk.Substring(0, directoryOnDisk.Length - 1); if (Verbose) StatusMessageTextWriter.WriteLine("adding selection '{0}' from dir '{1}'...", selectionCriteria, directoryOnDisk); Ionic.FileSelector ff = new Ionic.FileSelector(selectionCriteria, @@ -1444,7 +1444,7 @@ private bool Evaluate(Ionic.Zip.ZipEntry entry) // workitem 9174 if (slashSwapped != null) { - while (slashSwapped.EndsWith("\\")) + while (slashSwapped.EndsWith("\\", StringComparison.Ordinal)) slashSwapped = slashSwapped.Substring(0, slashSwapped.Length - 1); } foreach (Ionic.Zip.ZipEntry e in zip) diff --git a/src/Zip.Shared/ZipFile.cs b/src/Zip.Shared/ZipFile.cs index d5d83d1..9f60ee7 100644 --- a/src/Zip.Shared/ZipFile.cs +++ b/src/Zip.Shared/ZipFile.cs @@ -3160,7 +3160,7 @@ public ZipEntry this[String fileName] if (e.FileName.Replace("\\", "/") == fileName) return e; // check for a difference only in trailing slash - if (e.FileName.EndsWith("/")) + if (e.FileName.EndsWith("/", StringComparison.Ordinal)) { var fileNameNoSlash = e.FileName.Trim("/".ToCharArray()); if (fileNameNoSlash == fileName) return e; @@ -3179,7 +3179,7 @@ public ZipEntry this[String fileName] if (String.Compare(e.FileName.Replace("\\", "/"), fileName, StringComparison.CurrentCultureIgnoreCase) == 0) return e; // check for a difference only in trailing slash - if (e.FileName.EndsWith("/")) + if (e.FileName.EndsWith("/", StringComparison.Ordinal)) { var fileNameNoSlash = e.FileName.Trim("/".ToCharArray()); diff --git a/src/Zip.Shared/ZipOutputStream.cs b/src/Zip.Shared/ZipOutputStream.cs index 5f4c9f0..a2c677d 100644 --- a/src/Zip.Shared/ZipOutputStream.cs +++ b/src/Zip.Shared/ZipOutputStream.cs @@ -1391,7 +1391,7 @@ public ZipEntry PutNextEntry(String entryName) _currentEntry.AlternateEncoding = this.AlternateEncoding; _currentEntry.AlternateEncodingUsage = this.AlternateEncodingUsage; - if (entryName.EndsWith("/")) _currentEntry.MarkAsDirectory(); + if (entryName.EndsWith("/", StringComparison.Ordinal)) _currentEntry.MarkAsDirectory(); _currentEntry.EmitTimesInWindowsFormatWhenSaving = ((_timestamp & ZipEntryTimestamp.Windows) != 0); _currentEntry.EmitTimesInUnixFormatWhenSaving = ((_timestamp & ZipEntryTimestamp.Unix) != 0); diff --git a/src/Zlib.Shared/GZipStream.cs b/src/Zlib.Shared/GZipStream.cs index 875ed7f..5509230 100644 --- a/src/Zlib.Shared/GZipStream.cs +++ b/src/Zlib.Shared/GZipStream.cs @@ -189,7 +189,7 @@ public String FileName { _FileName = _FileName.Replace("/", "\\"); } - if (_FileName.EndsWith("\\")) + if (_FileName.EndsWith("\\", StringComparison.Ordinal)) throw new Exception("Illegal filename"); if (_FileName.IndexOf("\\") != -1) {