mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Merge pull request #52 from andreimedar:master
PiperOrigin-RevId: 334560525 Change-Id: I605ce78638ebfd7a88811879c4185bb4e107d915
This commit is contained in:
commit
d292a9af7b
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "oss-internship-2020/sapi_lodepng/lodepng"]
|
||||
path = oss-internship-2020/lodepng/lodepng
|
||||
url = https://github.com/lvandeve/lodepng
|
||||
[submodule "oss-internship-2020/openjpeg/openjpeg"]
|
||||
path = oss-internship-2020/openjpeg/openjpeg
|
||||
url = https://github.com/uclouvain/openjpeg.git
|
||||
|
3
oss-internship-2020/lodepng/.gitignore
vendored
Normal file
3
oss-internship-2020/lodepng/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
build/
|
||||
.clang-format
|
||||
.cache
|
80
oss-internship-2020/lodepng/CMakeLists.txt
Normal file
80
oss-internship-2020/lodepng/CMakeLists.txt
Normal file
@ -0,0 +1,80 @@
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(lodepng_sapi CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED 17)
|
||||
|
||||
# Apply the patches to the header file.
|
||||
add_custom_command(
|
||||
OUTPUT "${PROJECT_BINARY_DIR}/lodepng/lodepng.h" "${PROJECT_BINARY_DIR}/lodepng/lodepng.cpp"
|
||||
COMMENT "Applying patch to header file."
|
||||
COMMAND cp -r "${PROJECT_SOURCE_DIR}/lodepng" "${PROJECT_BINARY_DIR}/"
|
||||
COMMAND cp "${PROJECT_SOURCE_DIR}/patches/header.patch" "${PROJECT_BINARY_DIR}/lodepng/"
|
||||
COMMAND cd "${PROJECT_BINARY_DIR}/lodepng" && patch < header.patch
|
||||
)
|
||||
|
||||
# Build static library.
|
||||
add_library(lodepng STATIC
|
||||
"${PROJECT_BINARY_DIR}/lodepng/lodepng.cpp"
|
||||
"${PROJECT_BINARY_DIR}/lodepng/lodepng.h"
|
||||
)
|
||||
|
||||
target_include_directories(lodepng PUBLIC "${PROJECT_BINARY_DIR}/lodepng")
|
||||
|
||||
# Build SAPI library
|
||||
set(SAPI_ROOT "" CACHE PATH "Path to the Sandboxed API source tree")
|
||||
|
||||
add_subdirectory("${SAPI_ROOT}"
|
||||
"${CMAKE_BINARY_DIR}/sandboxed-api-build"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
add_sapi_library(
|
||||
lodepng_sapi
|
||||
|
||||
FUNCTIONS
|
||||
lodepng_decode_memory
|
||||
lodepng_decode32
|
||||
lodepng_decode24
|
||||
|
||||
lodepng_decode_file
|
||||
lodepng_decode32_file
|
||||
lodepng_decode24_file
|
||||
|
||||
lodepng_encode_memory
|
||||
lodepng_encode32
|
||||
lodepng_encode24
|
||||
|
||||
lodepng_encode_file
|
||||
lodepng_encode32_file
|
||||
lodepng_encode24_file
|
||||
|
||||
lodepng_save_file
|
||||
lodepng_load_file
|
||||
|
||||
INPUTS "${PROJECT_BINARY_DIR}/lodepng/lodepng.h"
|
||||
LIBRARY lodepng
|
||||
LIBRARY_NAME Lodepng
|
||||
NAMESPACE ""
|
||||
)
|
||||
|
||||
target_include_directories(lodepng_sapi INTERFACE
|
||||
"${PROJECT_BINARY_DIR}" # To find the generated SAPI header
|
||||
)
|
||||
|
||||
add_subdirectory(examples)
|
42
oss-internship-2020/lodepng/README.md
Normal file
42
oss-internship-2020/lodepng/README.md
Normal file
@ -0,0 +1,42 @@
|
||||
# LodePNG Sandboxed API
|
||||
|
||||
Sandboxed version of the [LodePNG](https://github.com/lvandeve/lodepng) library, using [Sandboxed API](https://github.com/google/sandboxed-api)
|
||||
|
||||
## Details
|
||||
|
||||
With Sandboxed API, many of the library's functions can be sandboxed. However, they need the `extern "C"` keyword defined so that name mangling does not happen, which is why a patch that adds it is used. The only differences are found in the header file. An alternative to this is to define another library that wraps every needed function, specifying the required keyword.
|
||||
|
||||
Even if many of the functions from the library can be sandboxed, there are some that are not supported (those which have `std::vector` parameters, overloaded functions etc.). If you really need these functions, a solution is to implement a custom library that wraps around these functions in order to make them compatible.
|
||||
|
||||
## Patches
|
||||
|
||||
In the **patches** folder there is a patch file that adds `extern "C"` to the required functions in the header file in order to sandbox them. This patch is applied automatically during the build phase.
|
||||
|
||||
## Build
|
||||
|
||||
First, run `git submodule update --init --recursive` to update submodules.
|
||||
After this, run the following commands:
|
||||
|
||||
`mkdir -p build && cd build`
|
||||
|
||||
`cmake .. -G Ninja`
|
||||
|
||||
`cmake --build .`
|
||||
|
||||
|
||||
The example binary files can be found in `build/examples`.
|
||||
|
||||
## Examples
|
||||
|
||||
The code found in the **examples** folder features a basic use case of the library. An image is generated, encoded into a file and then decoded to check that the values are the same. The encoding part was based on [this example](https://github.com/lvandeve/lodepng/blob/master/examples/example_encode.c) while decoding was based on [this](https://github.com/lvandeve/lodepng/blob/master/examples/example_decode.c).
|
||||
|
||||
This example code is structured as:
|
||||
- `main_unsandboxed.cc` - unsandboxed example
|
||||
- `main_sandboxed.cc` - sandboxed version of the example
|
||||
- `main_unit_test.cc` - tests(using [Google Test](https://github.com/google/googletest)).
|
||||
|
||||
On top of those files, there are other files used by all three of the examples:
|
||||
- `sandbox.h` - custom sandbox policy
|
||||
- `helpers.h` and `helpers.cc` - constants and functions used in the main files.
|
||||
|
||||
The executables generated from these files will create a temporary directory in the current working path. Inside that directory the two generated **png** files will be created. At the end, the directory is deleted. If those programs do not stop midway or return a failure code, then everything works fine.
|
70
oss-internship-2020/lodepng/examples/CMakeLists.txt
Normal file
70
oss-internship-2020/lodepng/examples/CMakeLists.txt
Normal file
@ -0,0 +1,70 @@
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Build the unsandboxed main
|
||||
add_executable(lodepng_unsandboxed
|
||||
main_unsandboxed.cc
|
||||
helpers.cc
|
||||
)
|
||||
|
||||
target_link_libraries(lodepng_unsandboxed PRIVATE
|
||||
lodepng
|
||||
sapi::sapi
|
||||
sandbox2::temp_file
|
||||
sandbox2::file_base
|
||||
sandbox2::fileops
|
||||
glog::glog
|
||||
)
|
||||
|
||||
# Build the sandboxed main
|
||||
add_executable(lodepng_sandboxed
|
||||
main_sandboxed.cc
|
||||
sandbox.h
|
||||
helpers.cc
|
||||
)
|
||||
|
||||
target_link_libraries(lodepng_sandboxed PRIVATE
|
||||
lodepng_sapi
|
||||
sapi::sapi
|
||||
sandbox2::temp_file
|
||||
sandbox2::fileops
|
||||
sapi::vars
|
||||
sapi::status
|
||||
glog::glog
|
||||
)
|
||||
|
||||
# Build the unit tests
|
||||
include(GoogleTest)
|
||||
enable_testing()
|
||||
|
||||
add_executable(main_unit_test
|
||||
main_unit_test.cc
|
||||
helpers.cc
|
||||
)
|
||||
|
||||
target_link_libraries(main_unit_test PRIVATE
|
||||
lodepng_sapi
|
||||
absl::memory
|
||||
absl::strings
|
||||
absl::time
|
||||
glog::glog
|
||||
sapi::flags
|
||||
sapi::sapi
|
||||
sandbox2::temp_file
|
||||
sandbox2::fileops
|
||||
sapi::status
|
||||
sapi::test_main
|
||||
sapi::vars
|
||||
)
|
||||
gtest_discover_tests(main_unit_test)
|
43
oss-internship-2020/lodepng/examples/helpers.cc
Normal file
43
oss-internship-2020/lodepng/examples/helpers.cc
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "helpers.h" // NOLINT(build/include)
|
||||
|
||||
#include "sandboxed_api/sandbox2/util/temp_file.h"
|
||||
|
||||
std::vector<uint8_t> GenerateValues() {
|
||||
std::vector<uint8_t> image;
|
||||
image.reserve(kImgLen);
|
||||
|
||||
for (int y = 0; y < kHeight; ++y) {
|
||||
for (int x = 0; x < kWidth; ++x) {
|
||||
image.push_back(255 * !(x & y));
|
||||
image.push_back(x ^ y);
|
||||
image.push_back(x | y);
|
||||
image.push_back(255);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
std::string CreateTempDirAtCWD() {
|
||||
std::string cwd = sandbox2::file_util::fileops::GetCWD();
|
||||
CHECK(!cwd.empty()) << "Could not get current working directory";
|
||||
cwd.append("/");
|
||||
|
||||
absl::StatusOr<std::string> result = sandbox2::CreateTempDir(cwd);
|
||||
CHECK(result.ok()) << "Could not create temporary directory";
|
||||
return result.value();
|
||||
}
|
39
oss-internship-2020/lodepng/examples/helpers.h
Normal file
39
oss-internship-2020/lodepng/examples/helpers.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef LODEPNG_EXAMPLES_HELPERS_H_
|
||||
#define LODEPNG_EXAMPLES_HELPERS_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||
#include "sandboxed_api/sandbox2/util/temp_file.h"
|
||||
|
||||
inline constexpr size_t kWidth = 512;
|
||||
inline constexpr size_t kHeight = 512;
|
||||
inline constexpr size_t kImgLen = kWidth * kHeight * 4;
|
||||
|
||||
// Returns a vector that contains values used for testing.
|
||||
// This part of code is taken from
|
||||
// https://github.com/lvandeve/lodepng/blob/master/examples/example_encode.c#L96-L104.
|
||||
// The generated image contains square fractals.
|
||||
std::vector<uint8_t> GenerateValues();
|
||||
|
||||
// Creates a temporary directory in the current working directory and returns
|
||||
// the path.
|
||||
std::string CreateTempDirAtCWD();
|
||||
|
||||
#endif // LODEPNG_EXAMPLES_HELPERS_H_
|
193
oss-internship-2020/lodepng/examples/main_sandboxed.cc
Normal file
193
oss-internship-2020/lodepng/examples/main_sandboxed.cc
Normal file
@ -0,0 +1,193 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "helpers.h" // NOLINT(build/include)
|
||||
#include "sandbox.h" // NOLINT(build/include)
|
||||
|
||||
void EncodeDecodeOneStep(SapiLodepngSandbox& sandbox, LodepngApi& api) {
|
||||
// Generate the values.
|
||||
std::vector<uint8_t> image = GenerateValues();
|
||||
|
||||
// Encode the image.
|
||||
sapi::v::Array<uint8_t> sapi_image(kImgLen);
|
||||
CHECK(std::copy(image.begin(), image.end(), sapi_image.GetData()))
|
||||
<< "Could not copy values";
|
||||
|
||||
sapi::v::ConstCStr sapi_filename("/output/out_generated1.png");
|
||||
|
||||
absl::StatusOr<unsigned int> result = api.lodepng_encode32_file(
|
||||
sapi_filename.PtrBefore(), sapi_image.PtrBefore(), kWidth, kHeight);
|
||||
|
||||
CHECK(result.ok()) << "encode32_file call failed";
|
||||
CHECK(!result.value()) << "Unexpected result from encode32_file call";
|
||||
|
||||
// After the image has been encoded, decode it to check that the
|
||||
// pixel values are the same.
|
||||
sapi::v::UInt sapi_width, sapi_height;
|
||||
sapi::v::IntBase<uint8_t*> sapi_image_ptr(0);
|
||||
|
||||
result = api.lodepng_decode32_file(
|
||||
sapi_image_ptr.PtrBoth(), sapi_width.PtrBoth(), sapi_height.PtrBoth(),
|
||||
sapi_filename.PtrBefore());
|
||||
|
||||
CHECK(result.ok()) << "decode32_file call failes";
|
||||
CHECK(!result.value()) << "Unexpected result from decode32_file call";
|
||||
|
||||
CHECK(sapi_width.GetValue() == kWidth) << "Widths differ";
|
||||
CHECK(sapi_height.GetValue() == kHeight) << "Heights differ";
|
||||
|
||||
// The pixels have been allocated inside the sandboxed process
|
||||
// memory, so we need to transfer them to this process.
|
||||
// Transferring the memory has the following steps:
|
||||
// 1) define an array with the required length.
|
||||
// 2) set the remote pointer for the array to specify where the memory
|
||||
// that will be transferred is located.
|
||||
// 3) transfer the memory to this process (this step is why we need
|
||||
// the pointer and the length).
|
||||
sapi::v::Array<uint8_t> sapi_pixels(kImgLen);
|
||||
sapi_pixels.SetRemote(sapi_image_ptr.GetValue());
|
||||
|
||||
CHECK(sandbox.TransferFromSandboxee(&sapi_pixels).ok())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
// Now, we can compare the values.
|
||||
CHECK(absl::equal(image.begin(), image.end(), sapi_pixels.GetData(),
|
||||
sapi_pixels.GetData() + kImgLen))
|
||||
<< "Values differ";
|
||||
|
||||
// Free the memory allocated inside the sandbox.
|
||||
CHECK(sandbox.GetRpcChannel()->Free(sapi_image_ptr.GetValue()).ok())
|
||||
<< "Could not free memory inside sandboxed process";
|
||||
}
|
||||
|
||||
void EncodeDecodeTwoSteps(SapiLodepngSandbox& sandbox, LodepngApi& api) {
|
||||
// Generate the values.
|
||||
std::vector<uint8_t> image = GenerateValues();
|
||||
|
||||
// Encode the image into memory first.
|
||||
sapi::v::Array<uint8_t> sapi_image(kImgLen);
|
||||
CHECK(std::copy(image.begin(), image.end(), sapi_image.GetData()))
|
||||
<< "Could not copy values";
|
||||
|
||||
sapi::v::ConstCStr sapi_filename("/output/out_generated2.png");
|
||||
|
||||
sapi::v::ULLong sapi_pngsize;
|
||||
sapi::v::IntBase<uint8_t*> sapi_png_ptr(0);
|
||||
|
||||
// Encode it into memory.
|
||||
absl::StatusOr<unsigned int> result =
|
||||
api.lodepng_encode32(sapi_png_ptr.PtrBoth(), sapi_pngsize.PtrBoth(),
|
||||
sapi_image.PtrBefore(), kWidth, kHeight);
|
||||
|
||||
CHECK(result.ok()) << "encode32 call failed";
|
||||
CHECK(!result.value()) << "Unexpected result from encode32 call";
|
||||
|
||||
// The new array (pointed to by sapi_png_ptr) is allocated
|
||||
// inside the sandboxed process so we need to transfer it to this
|
||||
// process.
|
||||
sapi::v::Array<uint8_t> sapi_png_array(sapi_pngsize.GetValue());
|
||||
sapi_png_array.SetRemote(sapi_png_ptr.GetValue());
|
||||
|
||||
CHECK(sandbox.TransferFromSandboxee(&sapi_png_array).ok())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
// Write the image into the file (from memory).
|
||||
result =
|
||||
api.lodepng_save_file(sapi_png_array.PtrBefore(), sapi_pngsize.GetValue(),
|
||||
sapi_filename.PtrBefore());
|
||||
|
||||
CHECK(result.ok()) << "save_file call failed";
|
||||
CHECK(!result.value()) << "Unexpected result from save_file call";
|
||||
|
||||
// Now, decode the image using the 2 steps in order to compare the values.
|
||||
sapi::v::UInt sapi_width, sapi_height;
|
||||
sapi::v::IntBase<uint8_t*> sapi_png_ptr2(0);
|
||||
sapi::v::ULLong sapi_pngsize2;
|
||||
|
||||
// Load the file in memory.
|
||||
result =
|
||||
api.lodepng_load_file(sapi_png_ptr2.PtrBoth(), sapi_pngsize2.PtrBoth(),
|
||||
sapi_filename.PtrBefore());
|
||||
|
||||
CHECK(result.ok()) << "load_file call failed";
|
||||
CHECK(!result.value()) << "Unexpected result from load_file call";
|
||||
|
||||
CHECK(sapi_pngsize.GetValue() == sapi_pngsize2.GetValue())
|
||||
<< "Png sizes differ";
|
||||
|
||||
// Transfer the png array.
|
||||
sapi::v::Array<uint8_t> sapi_png_array2(sapi_pngsize2.GetValue());
|
||||
sapi_png_array2.SetRemote(sapi_png_ptr2.GetValue());
|
||||
|
||||
CHECK(sandbox.TransferFromSandboxee(&sapi_png_array2).ok())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
// After the file is loaded, decode it so we have access to the values
|
||||
// directly.
|
||||
sapi::v::IntBase<uint8_t*> sapi_png_ptr3(0);
|
||||
result = api.lodepng_decode32(
|
||||
sapi_png_ptr3.PtrBoth(), sapi_width.PtrBoth(), sapi_height.PtrBoth(),
|
||||
sapi_png_array2.PtrBefore(), sapi_pngsize2.GetValue());
|
||||
|
||||
CHECK(result.ok()) << "decode32 call failed";
|
||||
CHECK(!result.value()) << "Unexpected result from decode32 call";
|
||||
|
||||
CHECK(sapi_width.GetValue() == kWidth) << "Widths differ";
|
||||
CHECK(sapi_height.GetValue() == kHeight) << "Heights differ";
|
||||
|
||||
// Transfer the pixels so they can be used here.
|
||||
sapi::v::Array<uint8_t> sapi_pixels(kImgLen);
|
||||
sapi_pixels.SetRemote(sapi_png_ptr3.GetValue());
|
||||
|
||||
CHECK(sandbox.TransferFromSandboxee(&sapi_pixels).ok())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
// Compare the values.
|
||||
CHECK(absl::equal(image.begin(), image.end(), sapi_pixels.GetData(),
|
||||
sapi_pixels.GetData() + kImgLen))
|
||||
<< "Values differ";
|
||||
|
||||
// Free the memory allocated inside the sandbox.
|
||||
CHECK(sandbox.GetRpcChannel()->Free(sapi_png_ptr.GetValue()).ok())
|
||||
<< "Could not free memory inside sandboxed process";
|
||||
CHECK(sandbox.GetRpcChannel()->Free(sapi_png_ptr2.GetValue()).ok())
|
||||
<< "Could not free memory inside sandboxed process";
|
||||
CHECK(sandbox.GetRpcChannel()->Free(sapi_png_ptr3.GetValue()).ok())
|
||||
<< "Could not free memory inside sandboxed process";
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
const std::string images_path = CreateTempDirAtCWD();
|
||||
CHECK(sandbox2::file_util::fileops::Exists(images_path, false))
|
||||
<< "Temporary directory does not exist";
|
||||
|
||||
SapiLodepngSandbox sandbox(images_path);
|
||||
CHECK(sandbox.Init().ok()) << "Error during sandbox initialization";
|
||||
|
||||
LodepngApi api(&sandbox);
|
||||
|
||||
EncodeDecodeOneStep(sandbox, api);
|
||||
EncodeDecodeTwoSteps(sandbox, api);
|
||||
|
||||
if (sandbox2::file_util::fileops::DeleteRecursively(images_path)) {
|
||||
LOG(WARNING) << "Temporary folder could not be deleted";
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
213
oss-internship-2020/lodepng/examples/main_unit_test.cc
Normal file
213
oss-internship-2020/lodepng/examples/main_unit_test.cc
Normal file
@ -0,0 +1,213 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "helpers.h" // NOLINT(build/include)
|
||||
#include "sandbox.h" // NOLINT(build/include)
|
||||
#include "gtest/gtest.h"
|
||||
#include "sandboxed_api/util/status_matchers.h"
|
||||
|
||||
using ::sapi::IsOk;
|
||||
using ::testing::Eq;
|
||||
using ::testing::IsTrue;
|
||||
using ::testing::NotNull;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(HelpersTest, CreateTempDirAtCWD) {
|
||||
const std::string images_path = CreateTempDirAtCWD();
|
||||
ASSERT_THAT(sandbox2::file_util::fileops::Exists(images_path, false),
|
||||
IsTrue())
|
||||
<< "Temporary directory does not exist";
|
||||
|
||||
EXPECT_THAT(sandbox2::file_util::fileops::DeleteRecursively(images_path),
|
||||
IsTrue())
|
||||
<< "Temporary directory could not be deleted";
|
||||
}
|
||||
|
||||
TEST(HelpersTest, GenerateValues) {
|
||||
EXPECT_THAT(GenerateValues().size(), Eq(kImgLen));
|
||||
}
|
||||
|
||||
TEST(LodePngTest, Init) {
|
||||
const std::string images_path = CreateTempDirAtCWD();
|
||||
ASSERT_THAT(sandbox2::file_util::fileops::Exists(images_path, false),
|
||||
IsTrue())
|
||||
<< "Temporary directory does not exist";
|
||||
|
||||
SapiLodepngSandbox sandbox(images_path);
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Error during sandbox init";
|
||||
|
||||
EXPECT_THAT(sandbox2::file_util::fileops::DeleteRecursively(images_path),
|
||||
IsTrue())
|
||||
<< "Temporary directory could not be deleted";
|
||||
}
|
||||
|
||||
// Generate an image, encode it, decode it and compare the pixels with the
|
||||
// initial values.
|
||||
TEST(LodePngTest, EncodeDecodeOneStep) {
|
||||
const std::string images_path = CreateTempDirAtCWD();
|
||||
ASSERT_THAT(sandbox2::file_util::fileops::Exists(images_path, false),
|
||||
IsTrue())
|
||||
<< "Temporary directory does not exist";
|
||||
|
||||
SapiLodepngSandbox sandbox(images_path);
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Error during sandbox initialization";
|
||||
LodepngApi api(&sandbox);
|
||||
|
||||
std::vector<uint8_t> image = GenerateValues();
|
||||
|
||||
sapi::v::Array<uint8_t> sapi_image(kImgLen);
|
||||
EXPECT_THAT(std::copy(image.begin(), image.end(), sapi_image.GetData()),
|
||||
IsTrue())
|
||||
<< "Could not copy values";
|
||||
|
||||
sapi::v::ConstCStr sapi_filename("/output/out_generated1.png");
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
unsigned int result,
|
||||
api.lodepng_encode32_file(sapi_filename.PtrBefore(),
|
||||
sapi_image.PtrBefore(), kWidth, kHeight));
|
||||
|
||||
ASSERT_THAT(result, Eq(0)) << "Unexpected result from encode32_file call";
|
||||
|
||||
sapi::v::UInt sapi_width, sapi_height;
|
||||
sapi::v::IntBase<uint8_t*> sapi_image_ptr(0);
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(result,
|
||||
api.lodepng_decode32_file(
|
||||
sapi_image_ptr.PtrBoth(), sapi_width.PtrBoth(),
|
||||
sapi_height.PtrBoth(), sapi_filename.PtrBefore()));
|
||||
|
||||
ASSERT_THAT(result, Eq(0)) << "Unexpected result from decode32_file call";
|
||||
|
||||
EXPECT_THAT(sapi_width.GetValue(), Eq(kWidth)) << "Widths differ";
|
||||
EXPECT_THAT(sapi_height.GetValue(), Eq(kHeight)) << "Heights differ";
|
||||
|
||||
sapi::v::Array<uint8_t> sapi_pixels(kImgLen);
|
||||
sapi_pixels.SetRemote(sapi_image_ptr.GetValue());
|
||||
|
||||
ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_pixels), IsOk())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
EXPECT_THAT(absl::equal(image.begin(), image.end(), sapi_pixels.GetData(),
|
||||
sapi_pixels.GetData() + kImgLen),
|
||||
IsTrue())
|
||||
<< "Values differ";
|
||||
|
||||
EXPECT_THAT(sandbox.GetRpcChannel()->Free(sapi_image_ptr.GetValue()), IsOk())
|
||||
<< "Could not free memory inside sandboxed process";
|
||||
|
||||
EXPECT_THAT(sandbox2::file_util::fileops::DeleteRecursively(images_path),
|
||||
IsTrue())
|
||||
<< "Temporary directory could not be deleted";
|
||||
}
|
||||
|
||||
// Similar to the previous test, only that we use encoding by saving the data in
|
||||
// memory and then writing it to the file and decoding by first decoding in
|
||||
// memory and then getting the actual pixel values.
|
||||
TEST(LodePngTest, EncodeDecodeTwoSteps) {
|
||||
const std::string images_path = CreateTempDirAtCWD();
|
||||
ASSERT_THAT(sandbox2::file_util::fileops::Exists(images_path, false),
|
||||
IsTrue())
|
||||
<< "Temporary directory does not exist";
|
||||
|
||||
SapiLodepngSandbox sandbox(images_path);
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Error during sandbox init";
|
||||
LodepngApi api(&sandbox);
|
||||
|
||||
std::vector<uint8_t> image = GenerateValues();
|
||||
|
||||
sapi::v::Array<uint8_t> sapi_image(kImgLen);
|
||||
EXPECT_THAT(std::copy(image.begin(), image.end(), sapi_image.GetData()),
|
||||
IsTrue())
|
||||
<< "Could not copy values";
|
||||
|
||||
sapi::v::ConstCStr sapi_filename("/output/out_generated2.png");
|
||||
|
||||
sapi::v::ULLong sapi_pngsize;
|
||||
sapi::v::IntBase<uint8_t*> sapi_png_ptr(0);
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
unsigned int result,
|
||||
api.lodepng_encode32(sapi_png_ptr.PtrBoth(), sapi_pngsize.PtrBoth(),
|
||||
sapi_image.PtrBefore(), kWidth, kHeight));
|
||||
|
||||
ASSERT_THAT(result, Eq(0)) << "Unexpected result from encode32 call";
|
||||
|
||||
sapi::v::Array<uint8_t> sapi_png_array(sapi_pngsize.GetValue());
|
||||
sapi_png_array.SetRemote(sapi_png_ptr.GetValue());
|
||||
|
||||
ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_png_array), IsOk())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
result,
|
||||
api.lodepng_save_file(sapi_png_array.PtrBefore(), sapi_pngsize.GetValue(),
|
||||
sapi_filename.PtrBefore()));
|
||||
|
||||
ASSERT_THAT(result, Eq(0)) << "Unexpected result from save_file call";
|
||||
|
||||
sapi::v::UInt sapi_width, sapi_height;
|
||||
sapi::v::IntBase<uint8_t*> sapi_png_ptr2(0);
|
||||
sapi::v::ULLong sapi_pngsize2;
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
result,
|
||||
api.lodepng_load_file(sapi_png_ptr2.PtrBoth(), sapi_pngsize2.PtrBoth(),
|
||||
sapi_filename.PtrBefore()));
|
||||
|
||||
ASSERT_THAT(result, Eq(0)) << "Unexpected result from load_file call";
|
||||
|
||||
EXPECT_THAT(sapi_pngsize.GetValue(), Eq(sapi_pngsize2.GetValue()))
|
||||
<< "Png sizes differ";
|
||||
|
||||
sapi::v::Array<uint8_t> sapi_png_array2(sapi_pngsize2.GetValue());
|
||||
sapi_png_array2.SetRemote(sapi_png_ptr2.GetValue());
|
||||
|
||||
ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_png_array2), IsOk())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
sapi::v::IntBase<uint8_t*> sapi_png_ptr3(0);
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
result,
|
||||
api.lodepng_decode32(sapi_png_ptr3.PtrBoth(), sapi_width.PtrBoth(),
|
||||
sapi_height.PtrBoth(), sapi_png_array2.PtrBefore(),
|
||||
sapi_pngsize2.GetValue()));
|
||||
|
||||
ASSERT_THAT(result, Eq(0)) << "Unexpected result from decode32 call";
|
||||
|
||||
EXPECT_THAT(sapi_width.GetValue(), Eq(kWidth)) << "Widths differ";
|
||||
EXPECT_THAT(sapi_height.GetValue(), Eq(kHeight)) << "Heights differ";
|
||||
|
||||
sapi::v::Array<uint8_t> sapi_pixels(kImgLen);
|
||||
sapi_pixels.SetRemote(sapi_png_ptr3.GetValue());
|
||||
|
||||
ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_pixels), IsOk())
|
||||
<< "Error during transfer from sandboxee";
|
||||
|
||||
EXPECT_THAT(absl::equal(image.begin(), image.end(), sapi_pixels.GetData(),
|
||||
sapi_pixels.GetData() + kImgLen),
|
||||
IsTrue())
|
||||
<< "Values differ";
|
||||
|
||||
EXPECT_THAT(sandbox.GetRpcChannel()->Free(sapi_png_ptr.GetValue()), IsOk());
|
||||
EXPECT_THAT(sandbox.GetRpcChannel()->Free(sapi_png_ptr2.GetValue()), IsOk());
|
||||
EXPECT_THAT(sandbox.GetRpcChannel()->Free(sapi_png_ptr3.GetValue()), IsOk());
|
||||
|
||||
EXPECT_THAT(sandbox2::file_util::fileops::DeleteRecursively(images_path),
|
||||
IsTrue())
|
||||
<< "Temporary directory could not be deleted";
|
||||
}
|
||||
|
||||
} // namespace
|
116
oss-internship-2020/lodepng/examples/main_unsandboxed.cc
Normal file
116
oss-internship-2020/lodepng/examples/main_unsandboxed.cc
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "helpers.h" // NOLINT(build/include)
|
||||
#include "lodepng.h" // NOLINT(build/include)
|
||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||
#include "sandboxed_api/sandbox2/util/path.h"
|
||||
|
||||
void EncodeDecodeOneStep(const std::string& images_path) {
|
||||
// Generate the values.
|
||||
std::vector<uint8_t> image = GenerateValues();
|
||||
|
||||
// Encode the image.
|
||||
const std::string filename =
|
||||
sandbox2::file::JoinPath(images_path, "/out_generated1.png");
|
||||
unsigned int result =
|
||||
lodepng_encode32_file(filename.c_str(), image.data(), kWidth, kHeight);
|
||||
|
||||
CHECK(!result) << "Unexpected result from encode32_file call";
|
||||
|
||||
// After the image has been encoded, decode it to check that the
|
||||
// pixel values are the same.
|
||||
unsigned int width, height;
|
||||
uint8_t* image2 = 0;
|
||||
|
||||
result = lodepng_decode32_file(&image2, &width, &height, filename.c_str());
|
||||
|
||||
CHECK(!result) << "Unexpected result from decode32_file call";
|
||||
|
||||
CHECK(width == kWidth) << "Widths differ";
|
||||
CHECK(height == kHeight) << "Heights differ";
|
||||
|
||||
// Now, we can compare the values.
|
||||
CHECK(absl::equal(image.begin(), image.end(), image2, image2 + kImgLen))
|
||||
<< "Values differ";
|
||||
|
||||
free(image2);
|
||||
}
|
||||
|
||||
void EncodeDecodeTwoSteps(const std::string& images_path) {
|
||||
// Generate the values.
|
||||
std::vector<uint8_t> image = GenerateValues();
|
||||
|
||||
// Encode the image into memory first.
|
||||
const std::string filename =
|
||||
sandbox2::file::JoinPath(images_path, "/out_generated2.png");
|
||||
uint8_t* png;
|
||||
size_t pngsize;
|
||||
|
||||
unsigned int result =
|
||||
lodepng_encode32(&png, &pngsize, image.data(), kWidth, kHeight);
|
||||
|
||||
CHECK(!result) << "Unexpected result from encode32 call";
|
||||
|
||||
// Write the image into the file (from memory).
|
||||
result = lodepng_save_file(png, pngsize, filename.c_str());
|
||||
|
||||
CHECK(!result) << "Unexpected result from save_file call";
|
||||
|
||||
// Now, decode the image using the 2 steps in order to compare the values.
|
||||
unsigned int width, height;
|
||||
uint8_t* png2;
|
||||
size_t pngsize2;
|
||||
|
||||
// Load the file in memory.
|
||||
result = lodepng_load_file(&png2, &pngsize2, filename.c_str());
|
||||
|
||||
CHECK(!result) << "Unexpected result from load_file call";
|
||||
CHECK(pngsize == pngsize2) << "Png sizes differ";
|
||||
|
||||
uint8_t* image2;
|
||||
result = lodepng_decode32(&image2, &width, &height, png2, pngsize2);
|
||||
|
||||
CHECK(!result) << "Unexpected result from decode32 call";
|
||||
CHECK(width == kWidth) << "Widths differ";
|
||||
CHECK(height == kHeight) << "Heights differ";
|
||||
|
||||
// Compare the values.
|
||||
CHECK(absl::equal(image.begin(), image.end(), image2, image2 + kImgLen))
|
||||
<< "Values differ";
|
||||
|
||||
free(png);
|
||||
free(png2);
|
||||
free(image2);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
const std::string images_path = CreateTempDirAtCWD();
|
||||
CHECK(sandbox2::file_util::fileops::Exists(images_path, false))
|
||||
<< "Temporary directory does not exist";
|
||||
|
||||
EncodeDecodeOneStep(images_path);
|
||||
EncodeDecodeTwoSteps(images_path);
|
||||
|
||||
if (sandbox2::file_util::fileops::DeleteRecursively(images_path)) {
|
||||
LOG(WARNING) << "Temporary folder could not be deleted";
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
49
oss-internship-2020/lodepng/examples/sandbox.h
Normal file
49
oss-internship-2020/lodepng/examples/sandbox.h
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef LODEPNG_EXAMPLES_SANDBOX_H_
|
||||
#define LODEPNG_EXAMPLES_SANDBOX_H_
|
||||
|
||||
#include <syscall.h>
|
||||
|
||||
#include "lodepng_sapi.sapi.h" // NOLINT(build/include)
|
||||
|
||||
class SapiLodepngSandbox : public LodepngSandbox {
|
||||
public:
|
||||
explicit SapiLodepngSandbox(const std::string& images_path)
|
||||
: images_path_(images_path) {}
|
||||
|
||||
private:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder*) override {
|
||||
return sandbox2::PolicyBuilder()
|
||||
.AllowRead()
|
||||
.AllowWrite()
|
||||
.AllowOpen()
|
||||
.AllowSystemMalloc()
|
||||
.AllowExit()
|
||||
.AllowStat()
|
||||
.AddDirectoryAt(images_path_, "/output/", /*is_ro=*/false)
|
||||
.AllowSyscalls({
|
||||
__NR_futex,
|
||||
__NR_lseek,
|
||||
__NR_close,
|
||||
})
|
||||
.BuildOrDie();
|
||||
}
|
||||
|
||||
const std::string images_path_;
|
||||
};
|
||||
|
||||
#endif // LODEPNG_EXAMPLES_SANDBOX__
|
86
oss-internship-2020/lodepng/patches/header.patch
Normal file
86
oss-internship-2020/lodepng/patches/header.patch
Normal file
@ -0,0 +1,86 @@
|
||||
--- lodepng.h 2020-09-11 08:41:22.280259945 +0000
|
||||
+++ lodepng2.h 2020-09-11 08:45:17.134266042 +0000
|
||||
@@ -89,6 +89,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+
|
||||
+
|
||||
#ifdef LODEPNG_COMPILE_CPP
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -126,6 +128,9 @@
|
||||
bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types.
|
||||
Return value: LodePNG error code (0 means no error).
|
||||
*/
|
||||
+
|
||||
+extern "C" {
|
||||
+
|
||||
unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const unsigned char* in, size_t insize,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
@@ -154,10 +159,12 @@
|
||||
/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/
|
||||
unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const char* filename);
|
||||
+
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
|
||||
+
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
/*
|
||||
Converts raw pixel data into a PNG image in memory. The colortype and bitdepth
|
||||
@@ -204,6 +211,9 @@
|
||||
/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/
|
||||
unsigned lodepng_encode24_file(const char* filename,
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
+
|
||||
+}
|
||||
+
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
|
||||
@@ -219,6 +229,8 @@
|
||||
unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
||||
const std::vector<unsigned char>& in,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
+
|
||||
+
|
||||
#ifdef LODEPNG_COMPILE_DISK
|
||||
/*
|
||||
Converts PNG file from disk to raw pixel data in memory.
|
||||
@@ -251,6 +263,7 @@
|
||||
unsigned encode(const std::string& filename,
|
||||
const std::vector<unsigned char>& in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
+
|
||||
#endif /* LODEPNG_COMPILE_DISK */
|
||||
#endif /* LODEPNG_COMPILE_ENCODER */
|
||||
} /* namespace lodepng */
|
||||
@@ -318,6 +331,7 @@
|
||||
|
||||
extern const LodePNGCompressSettings lodepng_default_compress_settings;
|
||||
void lodepng_compress_settings_init(LodePNGCompressSettings* settings);
|
||||
+
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_PNG
|
||||
@@ -943,6 +957,8 @@
|
||||
#endif /*LODEPNG_COMPILE_ZLIB*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_DISK
|
||||
+
|
||||
+extern "C" {
|
||||
/*
|
||||
Load a file from disk into buffer. The function allocates the out buffer, and
|
||||
after usage you should free it.
|
||||
@@ -962,6 +978,7 @@
|
||||
return value: error code (0 means ok)
|
||||
*/
|
||||
unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename);
|
||||
+}
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_CPP
|
Loading…
x
Reference in New Issue
Block a user