[Archive] Fixed permission handling for windows-zipped files 53/302653/1 tizen_6.0
authorPiotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Mon, 11 Dec 2023 10:51:01 +0000 (11:51 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Mon, 11 Dec 2023 12:17:44 +0000 (12:17 +0000)
[Issue] When having files with added P attribute on windows, then zipped
and unzipped on tizen using Web API, files have invalid access rights.

Reproduction:
1. create file on windows
2. add P attribute: attrib -a +p test_file.txt
3. zip file with 7-zip
4. copy to tizen device and unzip with webapi:
function errorCallback(error) {console.log(error);}
function successCallback() {console.log("done");}
function progressCallback(opId, val, name) {
  console.log(
      "extracting operation (: " + opId + ") is in progress (" + (val * 100).toFixed(1) + "%)");
}
function openSuccess(archive) {
  archive.extractAll("downloads", successCallback, errorCallback, progressCallback);
}
tizen.archive.open("downloads/test_kona.zip", "r", openSuccess);
5. check file permission:
 ------x--- 1 owner priv_mediastorage User::App::Shared 9 Oct 31 14:07 testfile.txt

[Verification] With this commit, above scenario ends with proper 755
permissions (for windows files), and recreated files permissions if
points 1-3 are done on ubuntu.
TCT passrate is 100%.

Change-Id: I8d6e3de036b39f5180b4773eaee5b710b0def9be
(cherry picked from commit 0985b4c8da445e34f517cfa63d94a82f00deabb5)

src/archive/un_zip.cc
src/archive/un_zip_extract_request.cc

index b381bdd..54953e6 100644 (file)
@@ -51,7 +51,8 @@ UnZip::UnZip(const std::string& filename)
 UnZip::~UnZip() {
   ScopeLogger();
   for (auto& x : path_access_map) {
-    LoggerD("Setting permission for path: %s  [%u] ", x.first.c_str(), x.second);
+    LoggerD("Setting permission for path: %s  [%o] ", x.first.c_str(),
+            x.second);
     if (chmod(x.first.c_str(), x.second) == -1) {
       LoggerE("Couldn't set permissions for: [%s] errno: %s", x.first.c_str(),
               GetErrorString(errno).c_str());
index 841767a..565fd65 100644 (file)
@@ -495,13 +495,25 @@ PlatformResult UnZipExtractRequest::handleFileEntry() {
 
 void UnZipExtractRequest::storePermissions() {
   // hold access information for later set
-  // The high 16 bits of the external file attributes seem to be used for OS-specific permissions
+  // The high 16 bits of the external file attributes seem to be used for
+  // OS-specific permissions https://unix.stackexchange.com/a/14727 this answer describes that
+  // structure is:
+  // * 4 bits - file type
+  // * 3 bits - setuid, setgid, sticky
+  // * 9 bits - permissions
   __mode_t mode = m_file_info.external_fa >> 16;
-  LoggerD("Storing permissions for %s: %u", m_filename_inzip, mode);
+  unsigned int linux_file_type = mode >> 12;
+  __mode_t default_mode = (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
   // check if proper permission mode is provided, if not use default 0775
-  if (mode == 0) {
-    mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
+  // validation is made for checking if both permissions and file type information is not zero
+  if (mode == 0 || linux_file_type == 0) {
+    mode = default_mode;
+    LoggerW(
+        "File %s has incomplete information for unix filesystem, using "
+        "default file permissions:  %o",
+        m_filename_inzip, mode);
   }
+  LoggerD("Storing permissions for %s: %o", m_filename_inzip, mode);
   m_owner.path_access_map[m_output_filepath.c_str()] = mode;
 }