1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "helpers.h" // NOLINT(build/include)
16 #include "sandbox.h" // NOLINT(build/include)
17 #include "gtest/gtest.h"
18 #include "sandboxed_api/util/status_matchers.h"
19
20 using ::sapi::IsOk;
21 using ::testing::Eq;
22 using ::testing::IsTrue;
23 using ::testing::NotNull;
24
25 namespace {
26
TEST(HelpersTest,CreateTempDirAtCWD)27 TEST(HelpersTest, CreateTempDirAtCWD) {
28 const std::string images_path = CreateTempDirAtCWD();
29 ASSERT_THAT(sapi::file_util::fileops::Exists(images_path, false), IsTrue())
30 << "Temporary directory does not exist";
31
32 EXPECT_THAT(sapi::file_util::fileops::DeleteRecursively(images_path),
33 IsTrue())
34 << "Temporary directory could not be deleted";
35 }
36
TEST(HelpersTest,GenerateValues)37 TEST(HelpersTest, GenerateValues) {
38 EXPECT_THAT(GenerateValues().size(), Eq(kImgLen));
39 }
40
TEST(LodePngTest,Init)41 TEST(LodePngTest, Init) {
42 const std::string images_path = CreateTempDirAtCWD();
43 ASSERT_THAT(sapi::file_util::fileops::Exists(images_path, false), IsTrue())
44 << "Temporary directory does not exist";
45
46 SapiLodepngSandbox sandbox(images_path);
47 ASSERT_THAT(sandbox.Init(), IsOk()) << "Error during sandbox init";
48
49 EXPECT_THAT(sapi::file_util::fileops::DeleteRecursively(images_path),
50 IsTrue())
51 << "Temporary directory could not be deleted";
52 }
53
54 // Generate an image, encode it, decode it and compare the pixels with the
55 // initial values.
TEST(LodePngTest,EncodeDecodeOneStep)56 TEST(LodePngTest, EncodeDecodeOneStep) {
57 const std::string images_path = CreateTempDirAtCWD();
58 ASSERT_THAT(sapi::file_util::fileops::Exists(images_path, false), IsTrue())
59 << "Temporary directory does not exist";
60
61 SapiLodepngSandbox sandbox(images_path);
62 ASSERT_THAT(sandbox.Init(), IsOk()) << "Error during sandbox initialization";
63 LodepngApi api(&sandbox);
64
65 std::vector<uint8_t> image = GenerateValues();
66
67 sapi::v::Array<uint8_t> sapi_image(kImgLen);
68 EXPECT_THAT(std::copy(image.begin(), image.end(), sapi_image.GetData()),
69 IsTrue())
70 << "Could not copy values";
71
72 sapi::v::ConstCStr sapi_filename("/output/out_generated1.png");
73
74 SAPI_ASSERT_OK_AND_ASSIGN(
75 unsigned int result,
76 api.lodepng_encode32_file(sapi_filename.PtrBefore(),
77 sapi_image.PtrBefore(), kWidth, kHeight));
78
79 ASSERT_THAT(result, Eq(0)) << "Unexpected result from encode32_file call";
80
81 sapi::v::UInt sapi_width, sapi_height;
82 sapi::v::IntBase<uint8_t*> sapi_image_ptr(0);
83
84 SAPI_ASSERT_OK_AND_ASSIGN(
85 result, api.lodepng_decode32_file(
86 sapi_image_ptr.PtrBoth(), sapi_width.PtrBoth(),
87 sapi_height.PtrBoth(), sapi_filename.PtrBefore()));
88
89 ASSERT_THAT(result, Eq(0)) << "Unexpected result from decode32_file call";
90
91 EXPECT_THAT(sapi_width.GetValue(), Eq(kWidth)) << "Widths differ";
92 EXPECT_THAT(sapi_height.GetValue(), Eq(kHeight)) << "Heights differ";
93
94 sapi::v::Array<uint8_t> sapi_pixels(kImgLen);
95 sapi_pixels.SetRemote(sapi_image_ptr.GetValue());
96
97 ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_pixels), IsOk())
98 << "Error during transfer from sandboxee";
99
100 EXPECT_THAT(absl::equal(image.begin(), image.end(), sapi_pixels.GetData(),
101 sapi_pixels.GetData() + kImgLen),
102 IsTrue())
103 << "Values differ";
104
105 EXPECT_THAT(sandbox.rpc_channel()->Free(sapi_image_ptr.GetValue()), IsOk())
106 << "Could not free memory inside sandboxed process";
107
108 EXPECT_THAT(sapi::file_util::fileops::DeleteRecursively(images_path),
109 IsTrue())
110 << "Temporary directory could not be deleted";
111 }
112
113 // Similar to the previous test, only that we use encoding by saving the data in
114 // memory and then writing it to the file and decoding by first decoding in
115 // memory and then getting the actual pixel values.
TEST(LodePngTest,EncodeDecodeTwoSteps)116 TEST(LodePngTest, EncodeDecodeTwoSteps) {
117 const std::string images_path = CreateTempDirAtCWD();
118 ASSERT_THAT(sapi::file_util::fileops::Exists(images_path, false), IsTrue())
119 << "Temporary directory does not exist";
120
121 SapiLodepngSandbox sandbox(images_path);
122 ASSERT_THAT(sandbox.Init(), IsOk()) << "Error during sandbox init";
123 LodepngApi api(&sandbox);
124
125 std::vector<uint8_t> image = GenerateValues();
126
127 sapi::v::Array<uint8_t> sapi_image(kImgLen);
128 EXPECT_THAT(std::copy(image.begin(), image.end(), sapi_image.GetData()),
129 IsTrue())
130 << "Could not copy values";
131
132 sapi::v::ConstCStr sapi_filename("/output/out_generated2.png");
133
134 sapi::v::ULLong sapi_pngsize;
135 sapi::v::IntBase<uint8_t*> sapi_png_ptr(0);
136
137 SAPI_ASSERT_OK_AND_ASSIGN(
138 unsigned int result,
139 api.lodepng_encode32(sapi_png_ptr.PtrBoth(), sapi_pngsize.PtrBoth(),
140 sapi_image.PtrBefore(), kWidth, kHeight));
141
142 ASSERT_THAT(result, Eq(0)) << "Unexpected result from encode32 call";
143
144 sapi::v::Array<uint8_t> sapi_png_array(sapi_pngsize.GetValue());
145 sapi_png_array.SetRemote(sapi_png_ptr.GetValue());
146
147 ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_png_array), IsOk())
148 << "Error during transfer from sandboxee";
149
150 SAPI_ASSERT_OK_AND_ASSIGN(
151 result,
152 api.lodepng_save_file(sapi_png_array.PtrBefore(), sapi_pngsize.GetValue(),
153 sapi_filename.PtrBefore()));
154
155 ASSERT_THAT(result, Eq(0)) << "Unexpected result from save_file call";
156
157 sapi::v::UInt sapi_width, sapi_height;
158 sapi::v::IntBase<uint8_t*> sapi_png_ptr2(0);
159 sapi::v::ULLong sapi_pngsize2;
160
161 SAPI_ASSERT_OK_AND_ASSIGN(
162 result,
163 api.lodepng_load_file(sapi_png_ptr2.PtrBoth(), sapi_pngsize2.PtrBoth(),
164 sapi_filename.PtrBefore()));
165
166 ASSERT_THAT(result, Eq(0)) << "Unexpected result from load_file call";
167
168 EXPECT_THAT(sapi_pngsize.GetValue(), Eq(sapi_pngsize2.GetValue()))
169 << "Png sizes differ";
170
171 sapi::v::Array<uint8_t> sapi_png_array2(sapi_pngsize2.GetValue());
172 sapi_png_array2.SetRemote(sapi_png_ptr2.GetValue());
173
174 ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_png_array2), IsOk())
175 << "Error during transfer from sandboxee";
176
177 sapi::v::IntBase<uint8_t*> sapi_png_ptr3(0);
178 SAPI_ASSERT_OK_AND_ASSIGN(
179 result,
180 api.lodepng_decode32(sapi_png_ptr3.PtrBoth(), sapi_width.PtrBoth(),
181 sapi_height.PtrBoth(), sapi_png_array2.PtrBefore(),
182 sapi_pngsize2.GetValue()));
183
184 ASSERT_THAT(result, Eq(0)) << "Unexpected result from decode32 call";
185
186 EXPECT_THAT(sapi_width.GetValue(), Eq(kWidth)) << "Widths differ";
187 EXPECT_THAT(sapi_height.GetValue(), Eq(kHeight)) << "Heights differ";
188
189 sapi::v::Array<uint8_t> sapi_pixels(kImgLen);
190 sapi_pixels.SetRemote(sapi_png_ptr3.GetValue());
191
192 ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_pixels), IsOk())
193 << "Error during transfer from sandboxee";
194
195 EXPECT_THAT(absl::equal(image.begin(), image.end(), sapi_pixels.GetData(),
196 sapi_pixels.GetData() + kImgLen),
197 IsTrue())
198 << "Values differ";
199
200 EXPECT_THAT(sandbox.rpc_channel()->Free(sapi_png_ptr.GetValue()), IsOk());
201 EXPECT_THAT(sandbox.rpc_channel()->Free(sapi_png_ptr2.GetValue()), IsOk());
202 EXPECT_THAT(sandbox.rpc_channel()->Free(sapi_png_ptr3.GetValue()), IsOk());
203
204 EXPECT_THAT(sapi::file_util::fileops::DeleteRecursively(images_path),
205 IsTrue())
206 << "Temporary directory could not be deleted";
207 }
208
209 } // namespace
210