Merge "libsnapshot: implement resume buffer" into main
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index ac58ba0..a8a7716 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -420,6 +420,7 @@
     },
     data: [
         "tools/testdata/cow_v2",
+        "tools/testdata/incompressible_block",
     ],
     auto_gen_config: true,
     require_root: false,
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp
index 35d74ba..2709059 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp
@@ -1522,6 +1522,37 @@
     ASSERT_TRUE(reader.GetFooter(&footer));
 }
 
+TEST_F(CowTest, DecompressIncompressibleBlock) {
+    auto fd = OpenTestFile("incompressible_block", O_RDONLY);
+    ASSERT_GE(fd, 0);
+
+    std::string original;
+    ASSERT_TRUE(android::base::ReadFdToString(fd, &original)) << strerror(errno);
+    ASSERT_EQ(original.size(), 4096);
+
+    CowOptions options;
+    options.compression = "gz";
+    auto writer = CreateCowWriter(2, options, GetCowFd());
+    ASSERT_NE(writer, nullptr);
+    ASSERT_TRUE(writer->AddRawBlocks(0, original.data(), original.size()));
+    ASSERT_TRUE(writer->Finalize());
+
+    CowReader reader;
+    ASSERT_TRUE(reader.Parse(cow_->fd));
+
+    auto iter = reader.GetOpIter();
+    ASSERT_NE(iter, nullptr);
+    ASSERT_FALSE(iter->AtEnd());
+
+    std::string block(original.size(), '\0');
+    ASSERT_EQ(iter->Get()->data_length, 4096);
+    ASSERT_TRUE(ReadData(reader, iter->Get(), block.data(), block.size()));
+
+    for (size_t i = 0; i < block.size(); i++) {
+        ASSERT_EQ(block[i], original[i]) << "mismatch at byte " << i;
+    }
+}
+
 }  // namespace snapshot
 }  // namespace android
 
diff --git a/fs_mgr/libsnapshot/tools/testdata/incompressible_block b/fs_mgr/libsnapshot/tools/testdata/incompressible_block
new file mode 100644
index 0000000..cc45cd0
--- /dev/null
+++ b/fs_mgr/libsnapshot/tools/testdata/incompressible_block
Binary files differ
diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp
index e7c6e04..32057b4 100644
--- a/run-as/run-as.cpp
+++ b/run-as/run-as.cpp
@@ -196,14 +196,6 @@
   }
   if (setegid(old_egid) == -1) error(1, errno, "couldn't restore egid");
 
-  // Handle a multi-user data path
-  if (userId > 0) {
-    free(info.data_dir);
-    if (asprintf(&info.data_dir, "/data/user/%d/%s", userId, pkgname) == -1) {
-      error(1, errno, "asprintf failed");
-    }
-  }
-
   if (info.uid == 0) {
     error(1, 0, "unknown package: %s", pkgname);
   }
@@ -226,6 +218,12 @@
     error(1, 0, "package not debuggable: %s", pkgname);
   }
 
+  // Ensure we have the right data path for the specific user.
+  free(info.data_dir);
+  if (asprintf(&info.data_dir, "/data/user/%d/%s", userId, pkgname) == -1) {
+    error(1, errno, "asprintf failed");
+  }
+
   // Check that the data directory path is valid.
   check_data_path(pkgname, info.data_dir, userAppId);