Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / zlib / google / zip_internal.cc
index b4f54d5..5ed2024 100644 (file)
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "third_party/zlib/google/zip.h"
+#include "third_party/zlib/google/zip_internal.h"
 
 #include <algorithm>
 
+#include "base/file_util.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
 
 #if defined(USE_SYSTEM_MINIZIP)
 #include <minizip/ioapi.h>
@@ -35,13 +37,11 @@ typedef struct {
 // Its only difference is that it treats the char* as UTF8 and
 // uses the Unicode version of CreateFile.
 void* ZipOpenFunc(void *opaque, const char* filename, int mode) {
-  DWORD desired_access, creation_disposition;
-  DWORD share_mode, flags_and_attributes;
+  DWORD desired_access = 0, creation_disposition = 0;
+  DWORD share_mode = 0, flags_and_attributes = 0;
   HANDLE file = 0;
   void* ret = NULL;
 
-  desired_access = share_mode = flags_and_attributes = 0;
-
   if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) {
     desired_access = GENERIC_READ;
     creation_disposition = OPEN_EXISTING;
@@ -54,7 +54,7 @@ void* ZipOpenFunc(void *opaque, const char* filename, int mode) {
     creation_disposition = CREATE_ALWAYS;
   }
 
-  base::string16 filename16 = UTF8ToUTF16(filename);
+  base::string16 filename16 = base::UTF8ToUTF16(filename);
   if ((filename != NULL) && (desired_access != 0)) {
     file = CreateFile(filename16.c_str(), desired_access, share_mode,
         NULL, creation_disposition, flags_and_attributes, NULL);
@@ -230,6 +230,28 @@ int GetErrorOfZipBuffer(void* /*opaque*/, void* /*stream*/) {
   return 0;
 }
 
+// Returns a zip_fileinfo struct with the time represented by |file_time|.
+zip_fileinfo TimeToZipFileInfo(const base::Time& file_time) {
+  base::Time::Exploded file_time_parts;
+  file_time.LocalExplode(&file_time_parts);
+
+  zip_fileinfo zip_info = {};
+  if (file_time_parts.year >= 1980) {
+    // This if check works around the handling of the year value in
+    // contrib/minizip/zip.c in function zip64local_TmzDateToDosDate
+    // It assumes that dates below 1980 are in the double digit format.
+    // Hence the fail safe option is to leave the date unset. Some programs
+    // might show the unset date as 1980-0-0 which is invalid.
+    zip_info.tmz_date.tm_year = file_time_parts.year;
+    zip_info.tmz_date.tm_mon = file_time_parts.month - 1;
+    zip_info.tmz_date.tm_mday = file_time_parts.day_of_month;
+    zip_info.tmz_date.tm_hour = file_time_parts.hour;
+    zip_info.tmz_date.tm_min = file_time_parts.minute;
+    zip_info.tmz_date.tm_sec = file_time_parts.second;
+  }
+
+  return zip_info;
+}
 }  // namespace
 
 namespace zip {
@@ -266,7 +288,7 @@ unzFile OpenHandleForUnzipping(HANDLE zip_handle) {
 #endif
 
 // static
-unzFile PreprareMemoryForUnzipping(const std::string& data) {
+unzFile PrepareMemoryForUnzipping(const std::string& data) {
   if (data.empty())
     return NULL;
 
@@ -312,5 +334,45 @@ zipFile OpenFdForZipping(int zip_fd, int append_flag) {
 }
 #endif
 
+zip_fileinfo GetFileInfoForZipping(const base::FilePath& path) {
+  base::Time file_time;
+  base::File::Info file_info;
+  if (base::GetFileInfo(path, &file_info))
+    file_time = file_info.last_modified;
+  return TimeToZipFileInfo(file_time);
+}
+
+bool ZipOpenNewFileInZip(zipFile zip_file,
+                         const std::string& str_path,
+                         const zip_fileinfo* file_info) {
+  // Section 4.4.4 http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+  // Setting the Language encoding flag so the file is told to be in utf-8.
+  const uLong LANGUAGE_ENCODING_FLAG = 0x1 << 11;
+
+  if (ZIP_OK != zipOpenNewFileInZip4(
+                    zip_file,  // file
+                    str_path.c_str(),  // filename
+                    file_info,  // zipfi
+                    NULL,  // extrafield_local,
+                    0u,  // size_extrafield_local
+                    NULL,  // extrafield_global
+                    0u,  // size_extrafield_global
+                    NULL,  // comment
+                    Z_DEFLATED,  // method
+                    Z_DEFAULT_COMPRESSION,  // level
+                    0,  // raw
+                    -MAX_WBITS,  // windowBits
+                    DEF_MEM_LEVEL,  // memLevel
+                    Z_DEFAULT_STRATEGY,  // strategy
+                    NULL,  // password
+                    0,  // crcForCrypting
+                    0,  // versionMadeBy
+                    LANGUAGE_ENCODING_FLAG)) {  // flagBase
+    DLOG(ERROR) << "Could not open zip file entry " << str_path;
+    return false;
+  }
+  return true;
+}
+
 }  // namespace internal
 }  // namespace zip