mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Merge branch 'main' into c-blosc
This commit is contained in:
commit
c93dae9519
53
.github/workflows/fedora-cmake.yml
vendored
53
.github/workflows/fedora-cmake.yml
vendored
|
@ -13,36 +13,55 @@ jobs:
|
|||
include:
|
||||
- container: fedora:35
|
||||
compiler: gcc # GCC 11
|
||||
ignore-errors: false
|
||||
# TODO(cblichmann): Add clang-13 build to matrix (currently fails)
|
||||
ignore-errors: true # Stack trace test fails on Fedora (issue #118)
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: ${{ matrix.ignore-errors }}
|
||||
|
||||
container:
|
||||
image: ${{ matrix.container }}
|
||||
env:
|
||||
RUN_CMD: docker exec --tty ${{matrix.compiler}}-build-container
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Prepare container
|
||||
# Note: For the sandbox tests to work, we need a privileged, unconfined
|
||||
# container that retains its capabilities.
|
||||
run: |
|
||||
docker run --name ${{matrix.compiler}}-build-container \
|
||||
--tty \
|
||||
--privileged \
|
||||
--cap-add ALL \
|
||||
--security-opt apparmor:unconfined \
|
||||
-v $GITHUB_WORKSPACE:$GITHUB_WORKSPACE \
|
||||
-e TERM=dumb \
|
||||
-e BUILD_TYPE \
|
||||
-e GITHUB_WORKSPACE \
|
||||
-d ${{matrix.container}} \
|
||||
sleep infinity
|
||||
|
||||
- name: Install build tools
|
||||
run: |
|
||||
dnf update -y
|
||||
dnf install -y git make automake patch glibc-static libstdc++-static \
|
||||
cmake ninja-build python3 python3-pip clang-devel libcap-devel
|
||||
|
||||
- name: Install/configure Clang compiler toolchain
|
||||
if: matrix.compiler == 'clang'
|
||||
run: |
|
||||
echo "CXX=clang++" >> $GITHUB_ENV
|
||||
echo "CC=clang" >> $GITHUB_ENV
|
||||
$RUN_CMD dnf update -y --quiet
|
||||
$RUN_CMD dnf install -y --quiet git make automake patch glibc-static \
|
||||
libstdc++-static cmake ninja-build python3 python3-pip clang-devel \
|
||||
libcap-devel
|
||||
|
||||
- name: Create Build Environment
|
||||
run: |
|
||||
pip3 install absl-py clang
|
||||
cmake -E make_directory $GITHUB_WORKSPACE/build
|
||||
$RUN_CMD pip3 install --progress-bar=off absl-py clang
|
||||
$RUN_CMD cmake -E make_directory $GITHUB_WORKSPACE/build
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake $GITHUB_WORKSPACE -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
run: |
|
||||
$RUN_CMD cmake -S $GITHUB_WORKSPACE -B $GITHUB_WORKSPACE/build \
|
||||
-G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
|
||||
- name: Build
|
||||
run: cmake --build $GITHUB_WORKSPACE --config $BUILD_TYPE
|
||||
run: |
|
||||
$RUN_CMD cmake --build $GITHUB_WORKSPACE/build --config $BUILD_TYPE
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
$RUN_CMD ctest --test-dir $GITHUB_WORKSPACE/build -C $BUILD_TYPE \
|
||||
--output-on-failure \
|
||||
-R SapiTest
|
||||
|
|
18
.github/workflows/ubuntu-cmake.yml
vendored
18
.github/workflows/ubuntu-cmake.yml
vendored
|
@ -62,17 +62,17 @@ jobs:
|
|||
- name: Create Build Environment
|
||||
run: |
|
||||
pip3 install absl-py clang
|
||||
cmake -E make_directory ${{runner.workspace}}/build
|
||||
cmake -E make_directory $GITHUB_WORKSPACE/build
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake $GITHUB_WORKSPACE -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
run: |
|
||||
cmake $GITHUB_WORKSPACE -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
run: |
|
||||
cmake --build $GITHUB_WORKSPACE --config $BUILD_TYPE
|
||||
|
||||
# TODO(cblichmann): Before enabling this, make sure all OSS tests pass
|
||||
#- name: Test
|
||||
# working-directory: ${{runner.workspace}}/build
|
||||
# run: ctest -C $BUILD_TYPE
|
||||
- name: Test
|
||||
run: |
|
||||
ctest $GITHUB_WORKSPACE -C $BUILD_TYPE --output-on-failure \
|
||||
-R SapiTest
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -4,9 +4,6 @@
|
|||
[submodule "oss-internship-2020/openjpeg/openjpeg"]
|
||||
path = oss-internship-2020/openjpeg/openjpeg
|
||||
url = https://github.com/uclouvain/openjpeg.git
|
||||
[submodule "oss-internship-2020/pffft/master"]
|
||||
path = oss-internship-2020/pffft/master
|
||||
url = https://bitbucket.org/jpommier/pffft/src/master/
|
||||
[submodule "oss-internship-2020/gdal/gdal"]
|
||||
path = oss-internship-2020/gdal/gdal
|
||||
url = https://github.com/OSGeo/gdal/
|
||||
|
|
|
@ -100,8 +100,7 @@ function(add_sapi_library)
|
|||
list(APPEND _sapi_exported_funcs "LINKER:--export-dynamic-symbol,${func}")
|
||||
endforeach()
|
||||
if(NOT _sapi_exported_funcs)
|
||||
set(_sapi_exported_funcs LINKER:--whole-archive
|
||||
LINKER:--allow-multiple-definition)
|
||||
set(_sapi_exported_funcs LINKER:--allow-multiple-definition)
|
||||
endif()
|
||||
|
||||
# The sandboxed binary
|
||||
|
@ -112,7 +111,7 @@ function(add_sapi_library)
|
|||
add_executable("${_sapi_bin}" "${_sapi_force_cxx_linkage}")
|
||||
target_link_libraries("${_sapi_bin}" PRIVATE
|
||||
-fuse-ld=gold
|
||||
"${_sapi_LIBRARY}"
|
||||
-Wl,--whole-archive "${_sapi_LIBRARY}" -Wl,--no-whole-archive
|
||||
sapi::client
|
||||
${CMAKE_DL_LIBS}
|
||||
)
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
|
||||
# Append to this list whenever a new sandboxed library is added to `contrib/`.
|
||||
set(SAPI_CONTRIB_SANDBOXES
|
||||
hunspell
|
||||
jsonnet
|
||||
libidn2
|
||||
pffft
|
||||
turbojpeg
|
||||
zopfli
|
||||
zstd
|
||||
)
|
||||
|
||||
|
|
|
@ -6,11 +6,15 @@ libraries.
|
|||
## Projects Sandboxed
|
||||
|
||||
Directory | Project | Home Page | Integration
|
||||
----------- | --------------------------------------------------------------- | -------------------------------------------------------------------- | -----------
|
||||
`c-blosc/` | c-blosc A blocking, shuffling and loss-less compression library | [github.com/Blosc/c-blosc](https://github.com/Blosc/c-blosc) | CMake
|
||||
`jsonnet/` | Jsonnet - The Data Templating Language | [github.com/google/jsonnet](https://github.com/google/jsonnet) | CMake
|
||||
------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------ | -----------
|
||||
`c-blosc/` | c-blosc - A blocking, shuffling and loss-less compression library | [github.com/Blosc/c-blosc](https://github.com/Blosc/c-blosc) | CMake
|
||||
`hunspell/` | Hunspell - The most popular spellchecking library | [github.com/hunspell/hunspell](https://github.com/hunspell/hunspell) | CMake
|
||||
`jsonnet/` | Jsonnet - The Data Templating Language | [github.com/google/jsonnet](https://github.com/google/jsonnet) | CMake
|
||||
`pffft/` | PFFFT - a pretty fast Fourier Transform | [bitbucket.org/jpommier/pffft.git](https://bitbucket.org/jpommier/pffft.git) | CMake
|
||||
`zopfli` | Zopfli - Compression Algorithm | [github.com/google/zopfli](https://github.com/google/zopfli) | CMake
|
||||
`zstd/` | Zstandard - Fast real-time compression algorithm | [github.com/facebook/zstd](https://github.com/facebook/zstd) | CMake
|
||||
`libidn2/` | libidn2 - GNU IDN library | [www.gnu.org/software/libidn/#libidn2](https://www.gnu.org/software/libidn/#libidn2) | CMake
|
||||
`turbojpeg/` | High-level JPEG library | [libjpeg-turbo.org/About/TurboJPEG](https://libjpeg-turbo.org/About/TurboJPEG) | CMake
|
||||
|
||||
## Projects Shipping with Sandboxed API Sandboxes
|
||||
|
||||
|
|
|
@ -21,15 +21,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|||
|
||||
set(SAPI_ROOT "" CACHE PATH "Path to the Sandboxed API source tree")
|
||||
|
||||
add_subdirectory(
|
||||
"${SAPI_ROOT}"
|
||||
if(NOT TARGET sapi::sapi)
|
||||
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
|
||||
)
|
||||
|
||||
FetchContent_Declare(
|
||||
libhunspell
|
||||
EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
FetchContent_Declare(libhunspell
|
||||
GIT_REPOSITORY https://github.com/hunspell/hunspell.git
|
||||
GIT_TAG 31e6d6323026a3bef12c5912ce032d88bfef2091
|
||||
)
|
||||
|
@ -44,13 +43,23 @@ if(NOT libhunspell_POPULATED)
|
|||
if(NOT _sapi_CONFIG_STATUS STREQUAL "${libhunspell_CONFIG_STATUS}")
|
||||
message("-- Configuring libhunspell...")
|
||||
execute_process(
|
||||
COMMAND autoreconf -vfi
|
||||
COMMAND ./configure --disable-dependency-tracking
|
||||
COMMAND autoreconf -i
|
||||
WORKING_DIRECTORY "${libhunspell_SOURCE_DIR}"
|
||||
RESULT_VARIABLE libhunspell_config_result
|
||||
RESULT_VARIABLE _sapi_libhunspell_autoreconf_result
|
||||
)
|
||||
if(NOT libhunspell_config_result EQUAL "0")
|
||||
message(FATAL_ERROR "Configuration for libhunspell failed")
|
||||
if(NOT _sapi_libhunspell_autoreconf_result EQUAL "0")
|
||||
message(FATAL_ERROR "Configuration for libhunspell failed: "
|
||||
"${_sapi_libhunspell_autoreconf_result}")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ./configure --disable-dependency-tracking
|
||||
--quiet
|
||||
WORKING_DIRECTORY "${libhunspell_SOURCE_DIR}"
|
||||
RESULT_VARIABLE _sapi_libhunspell_config_result
|
||||
)
|
||||
if(NOT _sapi_libhunspell_config_result EQUAL "0")
|
||||
message(FATAL_ERROR "Configuration for libhunspell failed: "
|
||||
"${_sapi_libhunspell_config_result}")
|
||||
endif()
|
||||
file(SHA256 "${libhunspell_SOURCE_DIR}/config.status" _sapi_CONFIG_STATUS)
|
||||
set(libhunspell_CONFIG_STATUS "${_sapi_CONFIG_STATUS}" CACHE INTERNAL "")
|
||||
|
@ -58,37 +67,37 @@ if(NOT libhunspell_POPULATED)
|
|||
endif()
|
||||
|
||||
add_library(hunspell STATIC
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/affentry.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/affentry.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/affixmgr.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/affixmgr.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/atypes.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/baseaffix.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/csutil.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/csutil.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/filemgr.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/filemgr.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/hashmgr.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/hashmgr.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/htypes.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/hunspell.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/hunspell.h
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/hunspell.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/hunzip.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/hunzip.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/langnum.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/phonet.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/phonet.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/replist.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/replist.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/suggestmgr.cxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/suggestmgr.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/utf_info.hxx
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell/w_char.hxx
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/affentry.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/affentry.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/affixmgr.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/affixmgr.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/atypes.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/baseaffix.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/csutil.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/csutil.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/filemgr.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/filemgr.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/hashmgr.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/hashmgr.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/htypes.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/hunspell.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/hunspell.h"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/hunspell.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/hunzip.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/hunzip.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/langnum.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/phonet.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/phonet.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/replist.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/replist.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/suggestmgr.cxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/suggestmgr.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/utf_info.hxx"
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell/w_char.hxx"
|
||||
)
|
||||
|
||||
target_include_directories(hunspell PUBLIC
|
||||
${libhunspell_SOURCE_DIR}/src/hunspell
|
||||
"${libhunspell_SOURCE_DIR}/src/hunspell"
|
||||
)
|
||||
|
||||
set(libhunspell_INCLUDE_DIR "${libhunspell_SOURCE_DIR}/src/hunspell")
|
||||
|
@ -112,7 +121,7 @@ add_sapi_library(
|
|||
|
||||
Hunspell_free_list
|
||||
INPUTS
|
||||
${libhunspell_INCLUDE_DIR}/hunspell.h
|
||||
"${libhunspell_INCLUDE_DIR}/hunspell.h"
|
||||
|
||||
LIBRARY hunspell
|
||||
LIBRARY_NAME Hunspell
|
||||
|
|
|
@ -35,6 +35,7 @@ class HunspellSapiSandbox : public HunspellSandbox {
|
|||
.AllowOpen()
|
||||
.AllowRead()
|
||||
.AllowWrite()
|
||||
.AllowGetPIDs()
|
||||
.AllowSystemMalloc()
|
||||
.AllowExit()
|
||||
.AllowSyscalls({
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# Jsonnet Sandboxed API
|
||||
|
||||
This library provides a sandboxed version of the
|
||||
This library was sandboxed as part of Google's summer 2020 internship program
|
||||
([blog post](https://security.googleblog.com/2020/12/improving-open-source-security-during.html)).
|
||||
|
||||
This directory contains a sandbox for the
|
||||
[Jsonnet](https://github.com/google/jsonnet) library.
|
||||
|
||||
## How to use from an existing Project
|
||||
|
|
|
@ -12,50 +12,48 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
cmake_minimum_required(VERSION 3.13..3.22)
|
||||
project(pffft CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
if(NOT TARGET sapi::sapi)
|
||||
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)
|
||||
endif()
|
||||
|
||||
include(CheckLibraryExists)
|
||||
|
||||
FetchContent_Declare(pffft
|
||||
GIT_REPOSITORY https://bitbucket.org/jpommier/pffft.git
|
||||
GIT_TAG 988259a41d1522047a9420e6265a6ba8289c1654 # 2021-12-02
|
||||
)
|
||||
FetchContent_MakeAvailable(pffft)
|
||||
|
||||
add_library(pffft STATIC
|
||||
master/pffft.c
|
||||
master/pffft.h
|
||||
master/fftpack.c
|
||||
master/fftpack.h
|
||||
"${pffft_SOURCE_DIR}/pffft.c"
|
||||
"${pffft_SOURCE_DIR}/pffft.h"
|
||||
"${pffft_SOURCE_DIR}/fftpack.c"
|
||||
"${pffft_SOURCE_DIR}/fftpack.h"
|
||||
)
|
||||
|
||||
add_executable(pffft_main
|
||||
master/test_pffft.c
|
||||
"${pffft_SOURCE_DIR}/test_pffft.c"
|
||||
)
|
||||
|
||||
target_link_libraries(pffft_main PRIVATE
|
||||
pffft
|
||||
)
|
||||
|
||||
set(MATH_LIBS "")
|
||||
include(CheckLibraryExists)
|
||||
check_library_exists(m sin "" LIBM)
|
||||
if(LIBM)
|
||||
list(APPEND MATH_LIBS "m")
|
||||
check_library_exists(m sin "" _sapi_HAVE_LIBM)
|
||||
if(_sapi_HAVE_LIBM)
|
||||
target_link_libraries(pffft PUBLIC
|
||||
m
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(pffft PUBLIC ${MATH_LIBS})
|
||||
|
||||
# Adding dependencies
|
||||
set(SAPI_ROOT "../.." CACHE PATH "Path to the Sandboxed API source tree")
|
||||
# Then configure:
|
||||
# mkdir -p build && cd build
|
||||
# cmake .. -G Ninja -DSAPI_ROOT=$HOME/sapi_root
|
||||
|
||||
set(SAPI_ENABLE_EXAMPLES OFF CACHE BOOL "")
|
||||
set(SAPI_ENABLE_TESTS OFF CACHE BOOL "")
|
||||
add_subdirectory("${SAPI_ROOT}"
|
||||
"${CMAKE_BINARY_DIR}/sandboxed-api-build"
|
||||
# Omit this to have the full Sandboxed API in IDE
|
||||
EXCLUDE_FROM_ALL)
|
||||
|
||||
add_sapi_library(pffft_sapi
|
||||
FUNCTIONS pffft_new_setup
|
||||
pffft_destroy_setup
|
||||
|
@ -83,22 +81,23 @@ add_sapi_library(pffft_sapi
|
|||
sinti
|
||||
sint
|
||||
|
||||
INPUTS master/pffft.h master/fftpack.h
|
||||
INPUTS "${pffft_SOURCE_DIR}/pffft.h"
|
||||
"${pffft_SOURCE_DIR}/fftpack.h"
|
||||
LIBRARY pffft
|
||||
LIBRARY_NAME Pffft
|
||||
|
||||
NAMESPACE ""
|
||||
)
|
||||
|
||||
add_library(sapi_contrib::pffft ALIAS pffft_sapi)
|
||||
target_include_directories(pffft_sapi INTERFACE
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
"${SAPI_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
add_executable(pffft_sandboxed
|
||||
main_pffft_sandboxed.cc
|
||||
)
|
||||
|
||||
target_link_libraries(pffft_sandboxed PRIVATE
|
||||
pffft_sapi
|
||||
sapi_contrib::pffft
|
||||
sapi::sapi
|
||||
)
|
|
@ -1,16 +1,35 @@
|
|||
# Sandboxing PFFFT library
|
||||
|
||||
This library was sandboxed as part of Google's summer 2020 internship program
|
||||
([blog post](https://security.googleblog.com/2020/12/improving-open-source-security-during.html)).
|
||||
|
||||
Build System: CMake
|
||||
OS: Linux
|
||||
|
||||
### Check out the PFFFT library & CMake set up
|
||||
```
|
||||
git submodule update --init --recursive
|
||||
### How to use from an existing Project
|
||||
|
||||
mkdir -p build && cd build
|
||||
cmake .. -G Ninja -DPFFFT_ROOT_DIR=$PWD
|
||||
ninjas
|
||||
If your project does not include Sandboxed API as a dependency yet, add the
|
||||
following lines to the main `CMakeLists.txt`:
|
||||
|
||||
```cmake
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(sandboxed-api
|
||||
GIT_REPOSITORY https://github.com/google/sandboxed-api
|
||||
GIT_TAG main # Or pin a specific commit/tag
|
||||
)
|
||||
FetchContent_MakeAvailable(sandboxed-api) # CMake 3.14 or higher
|
||||
|
||||
add_sapi_subdirectory(contrib/pffft)
|
||||
```
|
||||
|
||||
The `add_sapi_subdirectory()` macro sets up the source and binary directories
|
||||
for the sandboxed jsonnet targets.
|
||||
|
||||
Afterwards your project's code can link to `sapi_contrib::pffft` and use the
|
||||
generated header `pffft_sapi.sapi.h`. An example sandbox policy can be found
|
||||
in `main_pffft_sandboxed.cc`.
|
||||
|
||||
### For testing:
|
||||
`cd build`, then `./pffft_sandboxed`
|
||||
|
||||
|
@ -19,14 +38,15 @@ display custom info with
|
|||
`./pffft_sandboxed --logtostderr`
|
||||
|
||||
## ***About the project***
|
||||
*PFFFT library is concerned with 1D Fast-Fourier Transformations finding a
|
||||
|
||||
PFFFT library is concerned with 1D Fast-Fourier Transformations finding a
|
||||
compromise between accuracy and speed. It deals with real and complex
|
||||
vectors, both cases being illustrated in the testing part (`test_pffft.c`
|
||||
for initially and original version, `main_pffft_sandboxed.cc` for our
|
||||
currently implemented sandboxed version).
|
||||
The original files can be found at: https://bitbucket.org/jpommier/pffft/src.*
|
||||
|
||||
*The purpose of sandboxing is to limit the permissions and capabilities of
|
||||
The purpose of sandboxing is to limit the permissions and capabilities of
|
||||
library’s methods, in order to secure the usage of them.
|
||||
After obtaining the sandbox, the functions will be called through an
|
||||
Sandbox API (being called `api` in the current test) and so, the
|
||||
|
@ -50,10 +70,12 @@ Without using this type of argument when running, the output format is set
|
|||
by default.*
|
||||
|
||||
#### CMake observations resume:
|
||||
|
||||
* linking pffft and fftpack (which contains necessary functions for pffft)
|
||||
* set math library
|
||||
|
||||
#### Sandboxed main observations resume:
|
||||
|
||||
* containing two testing parts (fft / pffft benchmarks)
|
||||
* showing the performance of the transformations implies
|
||||
testing them through various FFT dimenstions.
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
#include <syscall.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include <ctime>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "gflags/gflags.h"
|
||||
#include "pffft_sapi.sapi.h" // NOLINT(build/include)
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
#include "sandboxed_api/vars.h"
|
44
contrib/turbojpeg/CMakeLists.txt
Normal file
44
contrib/turbojpeg/CMakeLists.txt
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Copyright 2022 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
|
||||
#
|
||||
# https://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.13..3.22)
|
||||
project(turbojpeg-sapi CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
if(NOT TARGET sapi::sapi)
|
||||
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)
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(TURBOJPEG REQUIRED IMPORTED_TARGET libturbojpeg)
|
||||
|
||||
add_sapi_library(turbojpeg_sapi
|
||||
INPUTS "${TURBOJPEG_INCLUDEDIR}/turbojpeg.h"
|
||||
LIBRARY turbojpeg
|
||||
LIBRARY_NAME TurboJPEG
|
||||
NAMESPACE "turbojpeg_sapi"
|
||||
)
|
||||
add_library(sapi_contrib::turbojpeg ALIAS turbojpeg_sapi)
|
||||
target_include_directories(turbojpeg_sapi INTERFACE
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
if(SAPI_ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
26
contrib/turbojpeg/tests/CMakeLists.txt
Normal file
26
contrib/turbojpeg/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2022 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
|
||||
#
|
||||
# https://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(GoogleTest)
|
||||
|
||||
add_executable(turbojpeg_sapi_test turbojpeg_sapi_test.cc)
|
||||
|
||||
target_link_libraries(turbojpeg_sapi_test PRIVATE
|
||||
turbojpeg_sapi
|
||||
sapi::base
|
||||
gtest
|
||||
gmock
|
||||
)
|
||||
|
||||
gtest_discover_tests(turbojpeg_sapi_test PROPERTIES ENVIRONMENT "TEST_FILES_DIR=${PROJECT_SOURCE_DIR}/tests")
|
BIN
contrib/turbojpeg/tests/sample.jpeg
Normal file
BIN
contrib/turbojpeg/tests/sample.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 257 B |
BIN
contrib/turbojpeg/tests/sample.rgb
Normal file
BIN
contrib/turbojpeg/tests/sample.rgb
Normal file
Binary file not shown.
181
contrib/turbojpeg/tests/turbojpeg_sapi_test.cc
Normal file
181
contrib/turbojpeg/tests/turbojpeg_sapi_test.cc
Normal file
|
@ -0,0 +1,181 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#include "../turbojpeg_sapi.h" // NOLINT(build/include)
|
||||
|
||||
#include <turbojpeg.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "gflags/gflags.h"
|
||||
#include "glog/logging.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "sandboxed_api/testing.h"
|
||||
#include "sandboxed_api/util/fileops.h"
|
||||
#include "sandboxed_api/util/path.h"
|
||||
#include "sandboxed_api/util/status_matchers.h"
|
||||
#include "turbojpeg_sapi.sapi.h" // NOLINT(build/include)
|
||||
|
||||
namespace {
|
||||
|
||||
using ::sapi::IsOk;
|
||||
using ::testing::Eq;
|
||||
using ::testing::Gt;
|
||||
using ::testing::Not;
|
||||
using ::testing::NotNull;
|
||||
using ::testing::StrEq;
|
||||
|
||||
class TurboJpegSapiSandboxTest : public testing::Test {
|
||||
protected:
|
||||
static void SetUpTestSuite() {
|
||||
ASSERT_THAT(getenv("TEST_FILES_DIR"), NotNull());
|
||||
sandbox_ = new TurboJpegSapiSandbox();
|
||||
ASSERT_THAT(sandbox_->Init(), IsOk());
|
||||
api_ = new turbojpeg_sapi::TurboJPEGApi(sandbox_);
|
||||
}
|
||||
static void TearDownTestSuite() {
|
||||
delete api_;
|
||||
delete sandbox_;
|
||||
}
|
||||
|
||||
static std::string GetTurboJpegErrorStr(sapi::v::Ptr* handle) {
|
||||
auto errmsg_ptr = api_->tjGetErrorStr2(handle);
|
||||
if (!errmsg_ptr.ok()) return "Error getting error message";
|
||||
auto errmsg =
|
||||
sandbox_->GetCString(sapi::v::RemotePtr(errmsg_ptr.value()), 256);
|
||||
if (!errmsg.ok()) return "Error getting error message";
|
||||
return errmsg.value();
|
||||
}
|
||||
static turbojpeg_sapi::TurboJPEGApi* api_;
|
||||
static TurboJpegSapiSandbox* sandbox_;
|
||||
};
|
||||
|
||||
turbojpeg_sapi::TurboJPEGApi* TurboJpegSapiSandboxTest::api_;
|
||||
TurboJpegSapiSandbox* TurboJpegSapiSandboxTest::sandbox_;
|
||||
|
||||
std::string GetTestFilePath(const std::string& filename) {
|
||||
return sapi::file::JoinPath(getenv("TEST_FILES_DIR"), filename);
|
||||
}
|
||||
|
||||
std::streamsize GetStreamSize(std::ifstream& stream) {
|
||||
stream.seekg(0, std::ios_base::end);
|
||||
std::streamsize ssize = stream.tellg();
|
||||
stream.seekg(0, std::ios_base::beg);
|
||||
|
||||
return ssize;
|
||||
}
|
||||
|
||||
absl::StatusOr<std::vector<uint8_t>> ReadFile(const std::string& in_file,
|
||||
size_t expected_size = SIZE_MAX) {
|
||||
std::ifstream f(GetTestFilePath(in_file));
|
||||
if (!f.is_open()) {
|
||||
return absl::UnavailableError("File could not be opened");
|
||||
}
|
||||
std::streamsize ssize = GetStreamSize(f);
|
||||
if (expected_size != SIZE_MAX && ssize != expected_size) {
|
||||
return absl::UnavailableError("Incorrect size of file");
|
||||
}
|
||||
std::vector<uint8_t> inbuf(ssize);
|
||||
f.read(reinterpret_cast<char*>(inbuf.data()), ssize);
|
||||
if (ssize != f.gcount()) {
|
||||
return absl::UnavailableError("Premature end of file");
|
||||
}
|
||||
if (f.fail() || f.eof()) {
|
||||
return absl::UnavailableError("Error reading file");
|
||||
}
|
||||
return inbuf;
|
||||
}
|
||||
|
||||
TEST_F(TurboJpegSapiSandboxTest, Compressor) {
|
||||
absl::StatusOr<void*> compression_handle_raw = api_->tjInitCompress();
|
||||
ASSERT_THAT(compression_handle_raw, IsOk());
|
||||
ASSERT_THAT(compression_handle_raw.value(), NotNull());
|
||||
sapi::v::RemotePtr compression_handle{compression_handle_raw.value()};
|
||||
auto result = ReadFile("sample.rgb", 12 * 67 * 3);
|
||||
ASSERT_THAT(result, IsOk());
|
||||
sapi::v::Array array(result->data(), result->size());
|
||||
|
||||
sapi::v::GenericPtr buffer;
|
||||
{
|
||||
sapi::v::ULong length{0};
|
||||
auto result = api_->tjCompress2(&compression_handle, array.PtrBefore(), 12,
|
||||
36, 67, TJPF_RGB, buffer.PtrAfter(),
|
||||
length.PtrBoth(), TJSAMP_444, 10, 0);
|
||||
ASSERT_THAT(result, IsOk());
|
||||
ASSERT_THAT(result.value(), Eq(0))
|
||||
<< "Error from sandboxee: "
|
||||
<< GetTurboJpegErrorStr(&compression_handle);
|
||||
ASSERT_TRUE(buffer.GetValue());
|
||||
ASSERT_TRUE(buffer.GetRemote());
|
||||
ASSERT_THAT(length.GetValue(), Gt(0));
|
||||
}
|
||||
auto value = buffer.GetValue();
|
||||
|
||||
auto destroy_result = api_->tjDestroy(&compression_handle);
|
||||
ASSERT_THAT(destroy_result, IsOk());
|
||||
ASSERT_THAT(destroy_result.value(), Eq(0));
|
||||
}
|
||||
|
||||
TEST_F(TurboJpegSapiSandboxTest, Decompressor) {
|
||||
absl::StatusOr<void*> decompression_handle_raw = api_->tjInitDecompress();
|
||||
ASSERT_THAT(decompression_handle_raw, IsOk());
|
||||
ASSERT_THAT(decompression_handle_raw.value(), NotNull());
|
||||
sapi::v::RemotePtr decompression_handle{decompression_handle_raw.value()};
|
||||
auto result = ReadFile("sample.jpeg");
|
||||
ASSERT_THAT(result, IsOk());
|
||||
sapi::v::Array array(result->data(), result->size());
|
||||
|
||||
sapi::v::Int width{0};
|
||||
sapi::v::Int height{0};
|
||||
sapi::v::Int subsamp{0};
|
||||
sapi::v::Int colorspace{0};
|
||||
auto decompress_result = api_->tjDecompressHeader3(
|
||||
&decompression_handle, array.PtrBefore(), result->size(),
|
||||
width.PtrAfter(), height.PtrAfter(), subsamp.PtrAfter(),
|
||||
colorspace.PtrAfter());
|
||||
ASSERT_THAT(decompress_result, IsOk());
|
||||
ASSERT_THAT(decompress_result.value(), Eq(0))
|
||||
<< "Error from sandboxee: "
|
||||
<< GetTurboJpegErrorStr(&decompression_handle);
|
||||
|
||||
ASSERT_THAT(width.GetValue(), Eq(67));
|
||||
ASSERT_THAT(height.GetValue(), Eq(12));
|
||||
ASSERT_THAT(subsamp.GetValue(), Eq(TJSAMP_GRAY));
|
||||
ASSERT_THAT(colorspace.GetValue(), Eq(TJCS_GRAY));
|
||||
|
||||
auto arr = sapi::v::Array<unsigned char>(12 * 67 * 3);
|
||||
decompress_result = api_->tjDecompress2(
|
||||
&decompression_handle, array.PtrBefore(), result->size(), arr.PtrAfter(),
|
||||
12, 36, 67, TJCS_RGB, 0);
|
||||
ASSERT_THAT(decompress_result, IsOk());
|
||||
EXPECT_THAT(decompress_result.value(), Eq(0))
|
||||
<< "Error from sandboxee: "
|
||||
<< GetTurboJpegErrorStr(&decompression_handle);
|
||||
|
||||
decompress_result = api_->tjDestroy(&decompression_handle);
|
||||
ASSERT_THAT(decompress_result, IsOk());
|
||||
ASSERT_THAT(decompress_result.value(), Eq(0));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
::google::InitGoogleLogging(program_invocation_short_name);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
44
contrib/turbojpeg/turbojpeg_sapi.h
Normal file
44
contrib/turbojpeg/turbojpeg_sapi.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 CONTRIB_TURBOJPEG_TURBOJPEG_SAPI_H_
|
||||
#define CONTRIB_TURBOJPEG_TURBOJPEG_SAPI_H_
|
||||
|
||||
#include <syscall.h>
|
||||
|
||||
#include "sandboxed_api/util/fileops.h"
|
||||
#include "turbojpeg_sapi.sapi.h" // NOLINT(build/include)
|
||||
class TurboJpegSapiSandbox : public turbojpeg_sapi::TurboJPEGSandbox {
|
||||
public:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder*) override {
|
||||
return sandbox2::PolicyBuilder()
|
||||
.AllowSystemMalloc()
|
||||
.AllowRead()
|
||||
.AllowStat()
|
||||
.AllowWrite()
|
||||
.AllowExit()
|
||||
.AllowSyscalls({
|
||||
__NR_futex,
|
||||
__NR_close,
|
||||
__NR_lseek,
|
||||
__NR_getpid,
|
||||
__NR_clock_gettime,
|
||||
})
|
||||
.AllowLlvmSanitizers()
|
||||
.BuildOrDie();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONTRIB_TURBOJPEG_TURBOJPEG_SAPI_H_
|
68
contrib/zopfli/CMakeLists.txt
Normal file
68
contrib/zopfli/CMakeLists.txt
Normal file
|
@ -0,0 +1,68 @@
|
|||
# Copyright 2022 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
|
||||
#
|
||||
# https://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.13..3.22)
|
||||
|
||||
project(sapi_zopfli CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
if(NOT TARGET sapi::sapi)
|
||||
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)
|
||||
endif()
|
||||
|
||||
FetchContent_Declare(zopfli
|
||||
GIT_REPOSITORY https://github.com/google/zopfli.git
|
||||
GIT_TAG 831773bc28e318b91a3255fa12c9fcde1606058b
|
||||
)
|
||||
FetchContent_MakeAvailable(zopfli)
|
||||
|
||||
add_sapi_library(
|
||||
sapi_zopfli
|
||||
|
||||
FUNCTIONS
|
||||
ZopfliInitOptions
|
||||
|
||||
ZopfliCompress
|
||||
|
||||
ZopfliDeflate
|
||||
ZopfliZlibCompress
|
||||
ZopfliGzipCompress
|
||||
|
||||
INPUTS
|
||||
${zopfli_SOURCE_DIR}/src/zopfli/deflate.h
|
||||
${zopfli_SOURCE_DIR}/src/zopfli/gzip_container.h
|
||||
${zopfli_SOURCE_DIR}/src/zopfli/zlib_container.h
|
||||
|
||||
LIBRARY Zopfli::libzopfli
|
||||
LIBRARY_NAME Zopfli
|
||||
NAMESPACE ""
|
||||
)
|
||||
add_library(sapi_contrib::zopfli ALIAS sapi_zopfli)
|
||||
target_include_directories(sapi_zopfli INTERFACE
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
"${SAPI_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
if(SAPI_ENABLE_EXAMPLES)
|
||||
add_subdirectory(example)
|
||||
endif()
|
||||
|
||||
if(SAPI_ENABLE_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif()
|
23
contrib/zopfli/example/CMakeLists.txt
Normal file
23
contrib/zopfli/example/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2022 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
add_executable(sapi_minizopfli
|
||||
main.cc
|
||||
../utils/utils_zopfli.cc
|
||||
)
|
||||
target_link_libraries(sapi_minizopfli PRIVATE
|
||||
sapi_contrib::zopfli
|
||||
sapi::sapi
|
||||
absl::flags_parse
|
||||
)
|
73
contrib/zopfli/example/main.cc
Normal file
73
contrib/zopfli/example/main.cc
Normal file
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 <unistd.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "contrib/zopfli/sandboxed.h"
|
||||
#include "contrib/zopfli/utils/utils_zopfli.h"
|
||||
|
||||
ABSL_FLAG(bool, zlib, false, "zlib compression");
|
||||
ABSL_FLAG(bool, gzip, false, "gzip compression");
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::string prog_name(argv[0]);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
std::vector<char*> args = absl::ParseCommandLine(argc, argv);
|
||||
|
||||
if (args.size() != 3) {
|
||||
std::cerr << "Usage:\n " << prog_name << " INPUT OUTPUT\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::ifstream infile(args[1], std::ios::binary);
|
||||
if (!infile.is_open()) {
|
||||
std::cerr << "Unable to open " << args[1] << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
std::ofstream outfile(args[2], std::ios::binary);
|
||||
if (!outfile.is_open()) {
|
||||
std::cerr << "Unable to open " << args[2] << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ZopfliSapiSandbox sandbox;
|
||||
if (!sandbox.Init().ok()) {
|
||||
std::cerr << "Unable to start sandbox\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ZopfliApi api(&sandbox);
|
||||
|
||||
ZopfliFormat format = ZOPFLI_FORMAT_DEFLATE;
|
||||
if (absl::GetFlag(FLAGS_zlib)) {
|
||||
format = ZOPFLI_FORMAT_ZLIB;
|
||||
} else if (absl::GetFlag(FLAGS_gzip)) {
|
||||
format = ZOPFLI_FORMAT_GZIP;
|
||||
}
|
||||
|
||||
absl::Status status = Compress(api, infile, outfile, format);
|
||||
if (!status.ok()) {
|
||||
std::cerr << "Unable to compress file.\n";
|
||||
std::cerr << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
BIN
contrib/zopfli/files/binary
Normal file
BIN
contrib/zopfli/files/binary
Normal file
Binary file not shown.
2000
contrib/zopfli/files/text
Normal file
2000
contrib/zopfli/files/text
Normal file
File diff suppressed because it is too large
Load Diff
49
contrib/zopfli/sandboxed.h
Normal file
49
contrib/zopfli/sandboxed.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 CONTRIB_ZOPFLI_SANDBOXED_
|
||||
#define CONTRIB_ZOPFLI_SANDBOXED_
|
||||
|
||||
#include <libgen.h>
|
||||
#include <syscall.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <memory>
|
||||
|
||||
#include "sapi_zopfli.sapi.h" // NOLINT(build/include)
|
||||
|
||||
class ZopfliSapiSandbox : public ZopfliSandbox {
|
||||
public:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder *) override {
|
||||
return sandbox2::PolicyBuilder()
|
||||
.AllowStaticStartup()
|
||||
.AllowWrite()
|
||||
.AllowExit()
|
||||
.AllowMmap()
|
||||
.AllowSystemMalloc()
|
||||
.AllowSyscalls({
|
||||
__NR_sysinfo,
|
||||
})
|
||||
#ifdef __NR_open
|
||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||
#endif
|
||||
#ifdef __NR_openat
|
||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||
#endif
|
||||
.BuildOrDie();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONTRIB_ZOPFLI_SANDBOXED_
|
28
contrib/zopfli/test/CMakeLists.txt
Normal file
28
contrib/zopfli/test/CMakeLists.txt
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2022 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
|
||||
#
|
||||
# https://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(GoogleTest)
|
||||
|
||||
add_executable(sapi_zopfli_test
|
||||
zopfli_test.cc
|
||||
../utils/utils_zopfli.cc
|
||||
)
|
||||
target_link_libraries(sapi_zopfli_test PRIVATE
|
||||
sapi_contrib::zopfli
|
||||
sapi::temp_file
|
||||
sapi::test_main
|
||||
)
|
||||
gtest_discover_tests(sapi_zopfli_test PROPERTIES
|
||||
ENVIRONMENT "TEST_FILES_DIR=${PROJECT_SOURCE_DIR}/files"
|
||||
)
|
98
contrib/zopfli/test/zopfli_test.cc
Normal file
98
contrib/zopfli/test/zopfli_test.cc
Normal file
|
@ -0,0 +1,98 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 <fstream>
|
||||
|
||||
#include "contrib/zopfli/sandboxed.h"
|
||||
#include "contrib/zopfli/utils/utils_zopfli.h"
|
||||
#include "sandboxed_api/util/path.h"
|
||||
#include "sandboxed_api/util/status_matchers.h"
|
||||
#include "sandboxed_api/util/temp_file.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::sapi::IsOk;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::Not;
|
||||
|
||||
std::string GetTestFilePath(const std::string& filename) {
|
||||
return sapi::file::JoinPath(getenv("TEST_FILES_DIR"), filename);
|
||||
}
|
||||
|
||||
std::string GetTemporaryFile(const std::string& filename) {
|
||||
absl::StatusOr<std::string> tmp_file =
|
||||
sapi::CreateNamedTempFileAndClose(filename);
|
||||
if (!tmp_file.ok()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *tmp_file);
|
||||
}
|
||||
|
||||
class TestText : public testing::TestWithParam<ZopfliFormat> {};
|
||||
|
||||
class TestBinary : public testing::TestWithParam<ZopfliFormat> {};
|
||||
|
||||
TEST_P(TestText, Compress) {
|
||||
ZopfliSapiSandbox sandbox;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZopfliApi api(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
std::string outfile_s = GetTemporaryFile("text.out");
|
||||
ASSERT_THAT(outfile_s, Not(IsEmpty()));
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
||||
std::ofstream outfile(outfile_s, std::ios::binary);
|
||||
ASSERT_TRUE(outfile.is_open());
|
||||
|
||||
absl::Status status = Compress(api, infile, outfile, GetParam());
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to compress file";
|
||||
|
||||
ASSERT_LT(outfile.tellp(), infile.tellg());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(SandboxTest, TestText,
|
||||
testing::Values(ZOPFLI_FORMAT_DEFLATE,
|
||||
ZOPFLI_FORMAT_GZIP,
|
||||
ZOPFLI_FORMAT_ZLIB));
|
||||
|
||||
TEST_P(TestBinary, Compress) {
|
||||
ZopfliSapiSandbox sandbox;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZopfliApi api(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("binary");
|
||||
std::string outfile_s = GetTemporaryFile("binary.out");
|
||||
ASSERT_THAT(outfile_s, Not(IsEmpty()));
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
||||
std::ofstream outfile(outfile_s, std::ios::binary);
|
||||
ASSERT_TRUE(outfile.is_open());
|
||||
|
||||
absl::Status status = Compress(api, infile, outfile, GetParam());
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to compress file";
|
||||
|
||||
ASSERT_LT(outfile.tellp(), infile.tellg());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(SandboxTest, TestBinary,
|
||||
testing::Values(ZOPFLI_FORMAT_DEFLATE,
|
||||
ZOPFLI_FORMAT_GZIP,
|
||||
ZOPFLI_FORMAT_ZLIB));
|
||||
} // namespace
|
56
contrib/zopfli/utils/utils_zopfli.cc
Normal file
56
contrib/zopfli/utils/utils_zopfli.cc
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 "contrib/zopfli/utils/utils_zopfli.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
absl::Status Compress(ZopfliApi& api, std::ifstream& instream,
|
||||
std::ofstream& outstream, ZopfliFormat format) {
|
||||
// Get size of Stream
|
||||
instream.seekg(0, std::ios_base::end);
|
||||
std::streamsize ssize = instream.tellg();
|
||||
instream.seekg(0, std::ios_base::beg);
|
||||
|
||||
// Read data
|
||||
sapi::v::Array<uint8_t> inbuf(ssize);
|
||||
instream.read(reinterpret_cast<char*>(inbuf.GetData()), ssize);
|
||||
if (instream.gcount() != ssize) {
|
||||
return absl::UnavailableError("Unable to read file");
|
||||
}
|
||||
|
||||
// Compress
|
||||
sapi::v::Struct<ZopfliOptions> options;
|
||||
SAPI_RETURN_IF_ERROR(api.ZopfliInitOptions(options.PtrAfter()));
|
||||
|
||||
sapi::v::GenericPtr outptr;
|
||||
sapi::v::IntBase<size_t> outsize(0);
|
||||
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
api.ZopfliCompress(options.PtrBefore(), format, inbuf.PtrBefore(), ssize,
|
||||
outptr.PtrAfter(), outsize.PtrBoth()));
|
||||
|
||||
// Get and save data
|
||||
sapi::v::Array<int8_t> outbuf(outsize.GetValue());
|
||||
outbuf.SetRemote(reinterpret_cast<void*>(outptr.GetValue()));
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferFromSandboxee(&outbuf));
|
||||
|
||||
outstream.write(reinterpret_cast<char*>(outbuf.GetData()), outbuf.GetSize());
|
||||
if (!outstream.good()) {
|
||||
return absl::UnavailableError("Unable to write file");
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
26
contrib/zopfli/utils/utils_zopfli.h
Normal file
26
contrib/zopfli/utils/utils_zopfli.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 CONTRIB_ZOPFLI_UTILS_UTILS_ZOPFLI_H_
|
||||
#define CONTRIB_ZOPFLI_UTILS_UTILS_ZOPFLI_H_
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "contrib/zopfli/sandboxed.h"
|
||||
|
||||
absl::Status Compress(ZopfliApi& api, std::ifstream& instream,
|
||||
std::ofstream& outstream, ZopfliFormat format);
|
||||
|
||||
#endif // CONTRIB_ZOPFLI_UTILS_UTILS_ZOPFLI_H_
|
|
@ -34,6 +34,8 @@ FetchContent_Declare(libzstd
|
|||
FetchContent_MakeAvailable(libzstd)
|
||||
|
||||
set(libzstd_INCLUDE_DIR "${libzstd_SOURCE_DIR}/lib")
|
||||
add_subdirectory(wrapper)
|
||||
|
||||
add_sapi_library(
|
||||
sapi_zstd
|
||||
|
||||
|
@ -70,10 +72,16 @@ add_sapi_library(
|
|||
|
||||
ZSTD_getFrameContentSize
|
||||
|
||||
ZSTD_compress_fd
|
||||
ZSTD_compressStream_fd
|
||||
|
||||
ZSTD_decompress_fd
|
||||
ZSTD_decompressStream_fd
|
||||
INPUTS
|
||||
${libzstd_INCLUDE_DIR}/zstd.h
|
||||
wrapper/wrapper_zstd.h
|
||||
|
||||
LIBRARY libzstd_static
|
||||
LIBRARY wrapper_zstd
|
||||
LIBRARY_NAME Zstd
|
||||
NAMESPACE ""
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
@ -25,10 +26,56 @@
|
|||
#include "contrib/zstd/sandboxed.h"
|
||||
#include "contrib/zstd/utils/utils_zstd.h"
|
||||
|
||||
ABSL_FLAG(bool, stream, false, "stream data to sandbox");
|
||||
ABSL_FLAG(bool, decompress, false, "decompress");
|
||||
ABSL_FLAG(bool, memory_mode, false, "in memory operations");
|
||||
ABSL_FLAG(uint32_t, level, 0, "compression level");
|
||||
|
||||
absl::Status Stream(ZstdApi& api, std::string infile_s, std::string outfile_s) {
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
if (!infile.is_open()) {
|
||||
return absl::UnavailableError(absl::StrCat("Unable to open ", infile_s));
|
||||
}
|
||||
std::ofstream outfile(outfile_s, std::ios::binary);
|
||||
if (!outfile.is_open()) {
|
||||
return absl::UnavailableError(absl::StrCat("Unable to open ", outfile_s));
|
||||
}
|
||||
|
||||
if (absl::GetFlag(FLAGS_memory_mode)) {
|
||||
if (absl::GetFlag(FLAGS_decompress)) {
|
||||
return DecompressInMemory(api, infile, outfile);
|
||||
}
|
||||
return CompressInMemory(api, infile, outfile, absl::GetFlag(FLAGS_level));
|
||||
}
|
||||
if (absl::GetFlag(FLAGS_decompress)) {
|
||||
return DecompressStream(api, infile, outfile);
|
||||
}
|
||||
return CompressStream(api, infile, outfile, absl::GetFlag(FLAGS_level));
|
||||
}
|
||||
|
||||
absl::Status FileDescriptor(ZstdApi& api, std::string infile_s,
|
||||
std::string outfile_s) {
|
||||
sapi::v::Fd infd(open(infile_s.c_str(), O_RDONLY));
|
||||
if (infd.GetValue() < 0) {
|
||||
return absl::UnavailableError(absl::StrCat("Unable to open ", infile_s));
|
||||
}
|
||||
sapi::v::Fd outfd(open(outfile_s.c_str(), O_WRONLY | O_CREAT));
|
||||
if (outfd.GetValue() < 0) {
|
||||
return absl::UnavailableError(absl::StrCat("Unable to open ", outfile_s));
|
||||
}
|
||||
|
||||
if (absl::GetFlag(FLAGS_memory_mode)) {
|
||||
if (absl::GetFlag(FLAGS_decompress)) {
|
||||
return DecompressInMemoryFD(api, infd, outfd);
|
||||
}
|
||||
return CompressInMemoryFD(api, infd, outfd, absl::GetFlag(FLAGS_level));
|
||||
}
|
||||
if (absl::GetFlag(FLAGS_decompress)) {
|
||||
return DecompressStreamFD(api, infd, outfd);
|
||||
}
|
||||
return CompressStreamFD(api, infd, outfd, absl::GetFlag(FLAGS_level));
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::string prog_name(argv[0]);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
@ -39,17 +86,6 @@ int main(int argc, char* argv[]) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::ifstream infile(args[1], std::ios::binary);
|
||||
if (!infile.is_open()) {
|
||||
std::cerr << "Unable to open " << args[1] << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
std::ofstream outfile(args[2], std::ios::binary);
|
||||
if (!outfile.is_open()) {
|
||||
std::cerr << "Unable to open " << args[2] << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ZstdSapiSandbox sandbox;
|
||||
if (!sandbox.Init().ok()) {
|
||||
std::cerr << "Unable to start sandbox\n";
|
||||
|
@ -59,16 +95,10 @@ int main(int argc, char* argv[]) {
|
|||
ZstdApi api(&sandbox);
|
||||
|
||||
absl::Status status;
|
||||
if (absl::GetFlag(FLAGS_memory_mode) && absl::GetFlag(FLAGS_decompress)) {
|
||||
status = DecompressInMemory(api, infile, outfile);
|
||||
} else if (absl::GetFlag(FLAGS_memory_mode) &&
|
||||
!absl::GetFlag(FLAGS_decompress)) {
|
||||
status = CompressInMemory(api, infile, outfile, absl::GetFlag(FLAGS_level));
|
||||
} else if (!absl::GetFlag(FLAGS_memory_mode) &&
|
||||
absl::GetFlag(FLAGS_decompress)) {
|
||||
status = DecompressStream(api, infile, outfile);
|
||||
if (absl::GetFlag(FLAGS_stream)) {
|
||||
status = Stream(api, argv[1], argv[2]);
|
||||
} else {
|
||||
status = CompressStream(api, infile, outfile, absl::GetFlag(FLAGS_level));
|
||||
status = FileDescriptor(api, argv[1], argv[2]);
|
||||
}
|
||||
|
||||
if (!status.ok()) {
|
||||
|
|
|
@ -27,10 +27,12 @@ class ZstdSapiSandbox : public ZstdSandbox {
|
|||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder*) override {
|
||||
return sandbox2::PolicyBuilder()
|
||||
.AllowDynamicStartup()
|
||||
.AllowRead()
|
||||
.AllowWrite()
|
||||
.AllowSystemMalloc()
|
||||
.AllowExit()
|
||||
.AllowSyscalls({__NR_recvmsg})
|
||||
.BuildOrDie();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
|
@ -101,11 +104,10 @@ TEST(SandboxTest, CheckCompressInMemory) {
|
|||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
absl::StatusOr<std::string> path =
|
||||
sapi::CreateNamedTempFileAndClose("out.zstd");
|
||||
ASSERT_THAT(path, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out.zstd"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
@ -126,10 +128,10 @@ TEST(SandboxTest, CheckDecompressInMemory) {
|
|||
|
||||
std::string infile_s = GetTestFilePath("text.blob.zstd");
|
||||
|
||||
absl::StatusOr<std::string> path = sapi::CreateNamedTempFileAndClose("out");
|
||||
ASSERT_THAT(path, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
@ -153,16 +155,15 @@ TEST(SandboxTest, CheckCompressAndDecompressInMemory) {
|
|||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
absl::StatusOr<std::string> path_middle =
|
||||
sapi::CreateNamedTempFileAndClose("middle.zstd");
|
||||
ASSERT_THAT(path_middle, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path_middle,
|
||||
sapi::CreateNamedTempFileAndClose("middle.zstd"));
|
||||
std::string middle_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path_middle);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path_middle);
|
||||
|
||||
absl::StatusOr<std::string> path = sapi::CreateNamedTempFileAndClose("out");
|
||||
ASSERT_THAT(path, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
@ -193,12 +194,10 @@ TEST(SandboxTest, CheckCompressStream) {
|
|||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
absl::StatusOr<std::string> path =
|
||||
sapi::CreateNamedTempFileAndClose("out.zstd");
|
||||
ASSERT_THAT(path, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out.zstd"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
@ -220,11 +219,10 @@ TEST(SandboxTest, CheckDecompressStream) {
|
|||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text.stream.zstd");
|
||||
|
||||
absl::StatusOr<std::string> path = sapi::CreateNamedTempFileAndClose("out");
|
||||
ASSERT_THAT(path, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
@ -248,16 +246,15 @@ TEST(SandboxTest, CheckCompressAndDecompressStream) {
|
|||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
absl::StatusOr<std::string> path_middle =
|
||||
sapi::CreateNamedTempFileAndClose("middle.zstd");
|
||||
ASSERT_THAT(path_middle, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path_middle,
|
||||
sapi::CreateNamedTempFileAndClose("middle.zstd"));
|
||||
std::string middle_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path_middle);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path_middle);
|
||||
|
||||
absl::StatusOr<std::string> path = sapi::CreateNamedTempFileAndClose("out");
|
||||
ASSERT_THAT(path, IsOk()) << "Could not create temp output file";
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *path);
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
std::ifstream infile(infile_s, std::ios::binary);
|
||||
ASSERT_TRUE(infile.is_open());
|
||||
|
@ -278,8 +275,235 @@ TEST(SandboxTest, CheckCompressAndDecompressStream) {
|
|||
ASSERT_TRUE(outfile.is_open());
|
||||
|
||||
status = DecompressStream(api, inmiddle, outfile);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to decompress";
|
||||
|
||||
ASSERT_TRUE(CompareFiles(infile_s, outfile_s));
|
||||
}
|
||||
|
||||
TEST(SandboxTest, CheckCompressInMemoryFD) {
|
||||
ZstdSapiSandbox sandbox;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out.zstd"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
sapi::v::Fd infd(open(infile_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(infd.GetValue(), 0);
|
||||
sapi::v::Fd outfd(open(outfile_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outfd.GetValue(), 0);
|
||||
|
||||
absl::Status status = CompressInMemoryFD(api, infd, outfd, 0);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to compress file in memory";
|
||||
|
||||
off_t inpos = lseek(infd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(inpos, 0);
|
||||
off_t outpos = lseek(outfd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(outpos, 0);
|
||||
|
||||
EXPECT_LT(outpos, inpos);
|
||||
}
|
||||
|
||||
TEST(SandboxTest, CheckDecompressInMemoryFD) {
|
||||
ZstdSapiSandbox sandbox;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text.blob.zstd");
|
||||
sapi::v::Fd infd(open(infile_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(infd.GetValue(), 0);
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
sapi::v::Fd outfd(open(outfile_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outfd.GetValue(), 0);
|
||||
|
||||
absl::Status status = DecompressInMemoryFD(api, infd, outfd);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to compress file in memory";
|
||||
|
||||
off_t inpos = lseek(infd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(inpos, 0);
|
||||
|
||||
off_t outpos = lseek(outfd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(outpos, 0);
|
||||
|
||||
EXPECT_GT(outpos, inpos);
|
||||
|
||||
ASSERT_TRUE(CompareFiles(GetTestFilePath("text"), outfile_s));
|
||||
}
|
||||
|
||||
TEST(SandboxTest, CheckCompressAndDecompressInMemoryFD) {
|
||||
ZstdSapiSandbox sandbox;
|
||||
absl::Status status;
|
||||
int ret;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path_middle,
|
||||
sapi::CreateNamedTempFileAndClose("middle.zstd"));
|
||||
std::string middle_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path_middle);
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
sapi::v::Fd infd(open(infile_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(infd.GetValue(), 0);
|
||||
|
||||
sapi::v::Fd outmiddlefd(open(middle_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outmiddlefd.GetValue(), 0);
|
||||
|
||||
status = CompressInMemoryFD(api, infd, outmiddlefd, 0);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to compress file in memory";
|
||||
|
||||
off_t inpos = lseek(infd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(inpos, 0);
|
||||
|
||||
off_t outpos = lseek(outmiddlefd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(outpos, 0);
|
||||
|
||||
EXPECT_LT(outpos, inpos);
|
||||
|
||||
infd.CloseLocalFd();
|
||||
outmiddlefd.CloseLocalFd();
|
||||
|
||||
sapi::v::Fd inmiddlefd(open(middle_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(inmiddlefd.GetValue(), 0);
|
||||
|
||||
sapi::v::Fd outfd(open(outfile_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outfd.GetValue(), 0);
|
||||
|
||||
status = DecompressInMemoryFD(api, inmiddlefd, outfd);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to decompress file in memory";
|
||||
|
||||
outfd.CloseLocalFd();
|
||||
inmiddlefd.CloseLocalFd();
|
||||
|
||||
ASSERT_TRUE(CompareFiles(infile_s, outfile_s));
|
||||
}
|
||||
|
||||
TEST(SandboxTest, CheckCompressStreamFD) {
|
||||
absl::Status status;
|
||||
ZstdSapiSandbox sandbox;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out.zstd"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
sapi::v::Fd infd(open(infile_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(infd.GetValue(), 0);
|
||||
|
||||
sapi::v::Fd outfd(open(outfile_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outfd.GetValue(), 0);
|
||||
|
||||
status = CompressStreamFD(api, infd, outfd, 0);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to compress stream";
|
||||
|
||||
off_t inpos = lseek(infd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(inpos, 0);
|
||||
|
||||
off_t outpos = lseek(outfd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(outpos, 0);
|
||||
|
||||
EXPECT_LT(outpos, inpos);
|
||||
}
|
||||
|
||||
TEST(SandboxTest, CheckDecompressStreamFD) {
|
||||
absl::Status status;
|
||||
ZstdSapiSandbox sandbox;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text.stream.zstd");
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
sapi::v::Fd infd(open(infile_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(infd.GetValue(), 0);
|
||||
|
||||
sapi::v::Fd outfd(open(outfile_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outfd.GetValue(), 0);
|
||||
|
||||
status = DecompressStreamFD(api, infd, outfd);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to decompress stream";
|
||||
|
||||
off_t inpos = lseek(infd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(inpos, 0);
|
||||
|
||||
off_t outpos = lseek(outfd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(outpos, 0);
|
||||
|
||||
EXPECT_GT(outpos, inpos);
|
||||
|
||||
ASSERT_TRUE(CompareFiles(GetTestFilePath("text"), outfile_s));
|
||||
}
|
||||
|
||||
TEST(SandboxTest, CheckCompressAndDecompressStreamFD) {
|
||||
ZstdSapiSandbox sandbox;
|
||||
absl::Status status;
|
||||
int ret;
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
ZstdApi api = ZstdApi(&sandbox);
|
||||
|
||||
std::string infile_s = GetTestFilePath("text");
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path_middle,
|
||||
sapi::CreateNamedTempFileAndClose("middle.zstd"));
|
||||
std::string middle_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path_middle);
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string path,
|
||||
sapi::CreateNamedTempFileAndClose("out"));
|
||||
std::string outfile_s =
|
||||
sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), path);
|
||||
|
||||
sapi::v::Fd infd(open(infile_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(infd.GetValue(), 0);
|
||||
|
||||
sapi::v::Fd outmiddlefd(open(middle_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outmiddlefd.GetValue(), 0);
|
||||
|
||||
status = CompressStreamFD(api, infd, outmiddlefd, 0);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to compress stream";
|
||||
|
||||
off_t inpos = lseek(infd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(inpos, 0);
|
||||
|
||||
off_t outmiddlepos = lseek(outmiddlefd.GetValue(), 0, SEEK_END);
|
||||
EXPECT_GE(outmiddlepos, 0);
|
||||
|
||||
EXPECT_LT(outmiddlepos, inpos);
|
||||
|
||||
infd.CloseLocalFd();
|
||||
outmiddlefd.CloseLocalFd();
|
||||
|
||||
sapi::v::Fd inmiddlefd(open(middle_s.c_str(), O_RDONLY));
|
||||
ASSERT_GE(inmiddlefd.GetValue(), 0);
|
||||
|
||||
sapi::v::Fd outfd(open(outfile_s.c_str(), O_WRONLY));
|
||||
ASSERT_GE(outfd.GetValue(), 0);
|
||||
|
||||
status = DecompressStreamFD(api, inmiddlefd, outfd);
|
||||
ASSERT_THAT(status, IsOk()) << "Unable to decompress stream";
|
||||
|
||||
ASSERT_TRUE(CompareFiles(infile_s, outfile_s));
|
||||
}
|
||||
|
||||
|
|
|
@ -241,3 +241,95 @@ absl::Status DecompressStream(ZstdApi& api, std::ifstream& in_stream,
|
|||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status CompressInMemoryFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd, int level) {
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&infd));
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&outfd));
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
int iserr,
|
||||
api.ZSTD_compress_fd(infd.GetRemoteFd(), outfd.GetRemoteFd(), 0));
|
||||
SAPI_ASSIGN_OR_RETURN(iserr, api.ZSTD_isError(iserr))
|
||||
if (iserr) {
|
||||
return absl::UnavailableError("Unable to compress file");
|
||||
}
|
||||
|
||||
infd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
outfd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status DecompressInMemoryFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd) {
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&infd));
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&outfd));
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(int iserr, api.ZSTD_decompress_fd(infd.GetRemoteFd(),
|
||||
outfd.GetRemoteFd()));
|
||||
SAPI_ASSIGN_OR_RETURN(iserr, api.ZSTD_isError(iserr))
|
||||
if (iserr) {
|
||||
return absl::UnavailableError("Unable to compress file");
|
||||
}
|
||||
|
||||
infd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
outfd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status CompressStreamFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd, int level) {
|
||||
SAPI_ASSIGN_OR_RETURN(ZSTD_CCtx * cctx, api.ZSTD_createCCtx());
|
||||
sapi::v::RemotePtr rcctx(cctx);
|
||||
|
||||
int iserr;
|
||||
SAPI_ASSIGN_OR_RETURN(iserr, api.ZSTD_CCtx_setParameter(
|
||||
&rcctx, ZSTD_c_compressionLevel, level));
|
||||
SAPI_ASSIGN_OR_RETURN(iserr, api.ZSTD_isError(iserr));
|
||||
if (iserr) {
|
||||
return absl::UnavailableError("Unable to set parameter l");
|
||||
}
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
iserr, api.ZSTD_CCtx_setParameter(&rcctx, ZSTD_c_checksumFlag, 1));
|
||||
SAPI_ASSIGN_OR_RETURN(iserr, api.ZSTD_isError(iserr));
|
||||
if (iserr) {
|
||||
return absl::UnavailableError("Unable to set parameter c");
|
||||
}
|
||||
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&infd));
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&outfd));
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(iserr,
|
||||
api.ZSTD_compressStream_fd(&rcctx, infd.GetRemoteFd(),
|
||||
outfd.GetRemoteFd()));
|
||||
if (iserr) {
|
||||
return absl::UnavailableError("Unable to compress");
|
||||
}
|
||||
|
||||
infd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
outfd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status DecompressStreamFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd) {
|
||||
SAPI_ASSIGN_OR_RETURN(ZSTD_DCtx * dctx, api.ZSTD_createDCtx());
|
||||
sapi::v::RemotePtr rdctx(dctx);
|
||||
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&infd));
|
||||
SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&outfd));
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(int iserr,
|
||||
api.ZSTD_decompressStream_fd(&rdctx, infd.GetRemoteFd(),
|
||||
outfd.GetRemoteFd()));
|
||||
if (iserr) {
|
||||
return absl::UnavailableError("Unable to decompress");
|
||||
}
|
||||
infd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
outfd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
|
|
@ -24,10 +24,18 @@ absl::Status CompressInMemory(ZstdApi& api, std::ifstream& in_stream,
|
|||
std::ofstream& out_stream, int level);
|
||||
absl::Status DecompressInMemory(ZstdApi& api, std::ifstream& in_stream,
|
||||
std::ofstream& out_stream);
|
||||
absl::Status CompressInMemoryFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd, int level);
|
||||
absl::Status DecompressInMemoryFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd);
|
||||
|
||||
absl::Status CompressStream(ZstdApi& api, std::ifstream& in_stream,
|
||||
std::ofstream& out_stream, int level);
|
||||
absl::Status DecompressStream(ZstdApi& api, std::ifstream& in_stream,
|
||||
std::ofstream& out_stream);
|
||||
absl::Status CompressStreamFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd, int level);
|
||||
absl::Status DecompressStreamFD(ZstdApi& api, sapi::v::Fd& infd,
|
||||
sapi::v::Fd& outfd);
|
||||
|
||||
#endif // CONTRIB_ZSTD_UTILS_UTILS_ZSTD_H_
|
||||
|
|
24
contrib/zstd/wrapper/CMakeLists.txt
Normal file
24
contrib/zstd/wrapper/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2022 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
add_library(wrapper_zstd STATIC
|
||||
wrapper_zstd.cc
|
||||
)
|
||||
target_link_libraries(wrapper_zstd PUBLIC
|
||||
libzstd_static
|
||||
)
|
||||
target_include_directories(wrapper_zstd PUBLIC
|
||||
"${SAPI_SOURCE_DIR}"
|
||||
"${libzstd_INCLUDE_DIR}"
|
||||
)
|
182
contrib/zstd/wrapper/wrapper_zstd.cc
Normal file
182
contrib/zstd/wrapper/wrapper_zstd.cc
Normal file
|
@ -0,0 +1,182 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 "contrib/zstd/wrapper/wrapper_zstd.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
constexpr size_t kFileMaxSize = 1024 * 1024 * 1024; // 1GB
|
||||
|
||||
off_t FDGetSize(int fd) {
|
||||
off_t size = lseek(fd, 0, SEEK_END);
|
||||
if (size < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (lseek(fd, 0, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int ZSTD_compress_fd(int fdin, int fdout, int level) {
|
||||
off_t sizein = FDGetSize(fdin);
|
||||
if (sizein <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t sizeout = ZSTD_compressBound(sizein);
|
||||
|
||||
auto bufin = std::make_unique<int8_t[]>(sizein);
|
||||
auto bufout = std::make_unique<int8_t[]>(sizeout);
|
||||
|
||||
if (read(fdin, bufin.get(), sizein) != sizein) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int retsize =
|
||||
ZSTD_compress(bufout.get(), sizeout, bufin.get(), sizein, level);
|
||||
if (ZSTD_isError(retsize)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write(fdout, bufout.get(), retsize) != retsize) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZSTD_compressStream_fd(ZSTD_CCtx* cctx, int fdin, int fdout) {
|
||||
size_t sizein = ZSTD_CStreamInSize();
|
||||
size_t sizeout = ZSTD_CStreamOutSize();
|
||||
|
||||
auto bufin = std::make_unique<int8_t[]>(sizein);
|
||||
auto bufout = std::make_unique<int8_t[]>(sizeout);
|
||||
|
||||
ssize_t size;
|
||||
while ((size = read(fdin, bufin.get(), sizein)) > 0) {
|
||||
ZSTD_inBuffer_s struct_in;
|
||||
struct_in.src = bufin.get();
|
||||
struct_in.pos = 0;
|
||||
struct_in.size = size;
|
||||
|
||||
ZSTD_EndDirective mode = ZSTD_e_continue;
|
||||
if (size < sizein) {
|
||||
mode = ZSTD_e_end;
|
||||
}
|
||||
|
||||
bool isdone = false;
|
||||
while (!isdone) {
|
||||
ZSTD_outBuffer_s struct_out;
|
||||
struct_out.dst = bufout.get();
|
||||
struct_out.pos = 0;
|
||||
struct_out.size = sizeout;
|
||||
|
||||
size_t remaining =
|
||||
ZSTD_compressStream2(cctx, &struct_out, &struct_in, mode);
|
||||
if (ZSTD_isError(remaining)) {
|
||||
return -1;
|
||||
}
|
||||
if (write(fdout, bufout.get(), struct_out.pos) != struct_out.pos) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode == ZSTD_e_continue) {
|
||||
isdone = (struct_in.pos == size);
|
||||
} else {
|
||||
isdone = (remaining == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZSTD_decompress_fd(int fdin, int fdout) {
|
||||
off_t sizein = FDGetSize(fdin);
|
||||
if (sizein <= 0) {
|
||||
return -1;
|
||||
}
|
||||
auto bufin = std::make_unique<int8_t[]>(sizein);
|
||||
if (read(fdin, bufin.get(), sizein) != sizein) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t sizeout = ZSTD_getFrameContentSize(bufin.get(), sizein);
|
||||
if (ZSTD_isError(sizeout) || sizeout > kFileMaxSize) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto bufout = std::make_unique<int8_t[]>(sizeout);
|
||||
|
||||
size_t desize = ZSTD_decompress(bufout.get(), sizeout, bufin.get(), sizein);
|
||||
if (ZSTD_isError(desize) || desize != sizeout) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write(fdout, bufout.get(), sizeout) != sizeout) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZSTD_decompressStream_fd(ZSTD_DCtx* dctx, int fdin, int fdout) {
|
||||
size_t sizein = ZSTD_CStreamInSize();
|
||||
size_t sizeout = ZSTD_CStreamOutSize();
|
||||
|
||||
auto bufin = std::make_unique<int8_t[]>(sizein);
|
||||
auto bufout = std::make_unique<int8_t[]>(sizeout);
|
||||
|
||||
ssize_t size;
|
||||
while ((size = read(fdin, bufin.get(), sizein)) > 0) {
|
||||
ZSTD_inBuffer_s struct_in;
|
||||
struct_in.src = bufin.get();
|
||||
struct_in.pos = 0;
|
||||
struct_in.size = size;
|
||||
|
||||
while (struct_in.pos < size) {
|
||||
ZSTD_outBuffer_s struct_out;
|
||||
struct_out.dst = bufout.get();
|
||||
struct_out.pos = 0;
|
||||
struct_out.size = sizeout;
|
||||
|
||||
size_t ret = ZSTD_decompressStream(dctx, &struct_out, &struct_in);
|
||||
if (ZSTD_isError(ret)) {
|
||||
return -1;
|
||||
}
|
||||
if (write(fdout, bufout.get(), struct_out.pos) != struct_out.pos) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
28
contrib/zstd/wrapper/wrapper_zstd.h
Normal file
28
contrib/zstd/wrapper/wrapper_zstd.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2022 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
|
||||
//
|
||||
// https://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 CONTRIB_ZSTD_WRAPPER_WRAPPER_ZSTD_H_
|
||||
#define CONTRIB_ZSTD_WRAPPER_WRAPPER_ZSTD_H_
|
||||
|
||||
#include <zstd.h>
|
||||
|
||||
extern "C" {
|
||||
int ZSTD_compress_fd(int fdin, int fdout, int level);
|
||||
int ZSTD_compressStream_fd(ZSTD_CCtx* cctx, int fdin, int fdout);
|
||||
|
||||
int ZSTD_decompress_fd(int fdin, int fdout);
|
||||
int ZSTD_decompressStream_fd(ZSTD_DCtx* dctx, int fdin, int fdout);
|
||||
};
|
||||
|
||||
#endif // CONTRIB_ZSTD_WRAPPER_WRAPPER_ZSTD_H_
|
3
oss-internship-2020/pffft/.gitignore
vendored
3
oss-internship-2020/pffft/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
*.o
|
||||
*.a
|
||||
pffft_main
|
|
@ -36,7 +36,7 @@ sapi_library(
|
|||
cc_binary(
|
||||
name = "main_zlib",
|
||||
srcs = ["main_zlib.cc"],
|
||||
copts = sapi_platform_copts(["-Wframe-larger-than=65536"]),
|
||||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
":zlib-sapi",
|
||||
":zlib-sapi_embed",
|
||||
|
|
|
@ -17,7 +17,7 @@ add_sapi_library(zlib-sapi
|
|||
FUNCTIONS deflateInit_
|
||||
deflate
|
||||
deflateEnd
|
||||
INPUTS ${ZLIB_INCLUDE_DIRS}/zlib.h
|
||||
INPUTS "${ZLIB_INCLUDE_DIRS}/zlib.h"
|
||||
LIBRARY ZLIB::ZLIB
|
||||
LIBRARY_NAME Zlib
|
||||
NAMESPACE "sapi::zlib"
|
||||
|
|
|
@ -555,9 +555,11 @@ bool Comms::Recv(void* data, size_t len) {
|
|||
// Internal helper method (low level).
|
||||
bool Comms::RecvTL(uint32_t* tag, size_t* length) {
|
||||
if (!Recv(reinterpret_cast<uint8_t*>(tag), sizeof(*tag))) {
|
||||
SAPI_RAW_VLOG(2, "RecvTL: Can't read tag");
|
||||
return false;
|
||||
}
|
||||
if (!Recv(reinterpret_cast<uint8_t*>(length), sizeof(*length))) {
|
||||
SAPI_RAW_VLOG(2, "RecvTL: Can't read length for tag %u", *tag);
|
||||
return false;
|
||||
}
|
||||
if (*length > GetMaxMsgSize()) {
|
||||
|
|
|
@ -57,4 +57,5 @@ sh_test(
|
|||
name = "static_sandbox_test",
|
||||
srcs = ["static_sandbox_test.sh"],
|
||||
data = [":static_sandbox"],
|
||||
tags = ["no_qemu_user_mode"],
|
||||
)
|
||||
|
|
|
@ -37,9 +37,6 @@ cc_binary(
|
|||
name = "zpipe",
|
||||
srcs = ["zpipe.c"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = [
|
||||
"fully_static_link", # link libc statically
|
||||
],
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
deps = ["@net_zlib//:zlib"],
|
||||
)
|
||||
|
|
|
@ -24,7 +24,6 @@ target_link_libraries(sandbox2_zpipe_sandbox PRIVATE
|
|||
absl::memory
|
||||
sandbox2::bpf_helper
|
||||
sandbox2::comms
|
||||
# sandbox2::ipc
|
||||
sapi::runfiles
|
||||
sandbox2::sandbox2
|
||||
sapi::base
|
||||
|
@ -38,5 +37,6 @@ add_executable(sandbox2_zpipe
|
|||
set_target_properties(sandbox2_zpipe PROPERTIES OUTPUT_NAME zpipe)
|
||||
add_executable(sandbox2::zpipe ALIAS sandbox2_zpipe)
|
||||
target_link_libraries(sandbox2_zpipe PRIVATE
|
||||
-static
|
||||
ZLIB::ZLIB
|
||||
)
|
||||
|
|
|
@ -54,7 +54,7 @@ std::unique_ptr<sandbox2::Policy> GetPolicy() {
|
|||
// Allow write on STDOUT / STDERR.
|
||||
.AddPolicyOnSyscall(__NR_write,
|
||||
{ARG_32(0), JEQ32(1, ALLOW), JEQ32(2, ALLOW)})
|
||||
.AllowSyscall(__NR_fstat)
|
||||
.AllowStat()
|
||||
.AllowStaticStartup()
|
||||
.AllowSystemMalloc()
|
||||
.AllowExit()
|
||||
|
|
|
@ -653,12 +653,10 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
|||
BlockSyscallWithErrno(__NR_readlink, ENOENT);
|
||||
#endif
|
||||
|
||||
if constexpr (sapi::host_cpu::IsArm()) {
|
||||
AddPolicyOnSyscall(__NR_mprotect, {
|
||||
ARG_32(2),
|
||||
JEQ32(PROT_READ, ALLOW),
|
||||
});
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -884,7 +882,7 @@ PolicyBuilder& PolicyBuilder::AddFile(absl::string_view path, bool is_ro) {
|
|||
|
||||
PolicyBuilder& PolicyBuilder::AddFileAt(absl::string_view outside,
|
||||
absl::string_view inside, bool is_ro) {
|
||||
EnableNamespaces();
|
||||
EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||
|
||||
auto valid_outside = ValidateAbsolutePath(outside);
|
||||
if (!valid_outside.ok()) {
|
||||
|
@ -912,7 +910,7 @@ PolicyBuilder& PolicyBuilder::AddFileAt(absl::string_view outside,
|
|||
|
||||
PolicyBuilder& PolicyBuilder::AddLibrariesForBinary(
|
||||
absl::string_view path, absl::string_view ld_library_path) {
|
||||
EnableNamespaces();
|
||||
EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||
|
||||
auto valid_path = ValidatePath(path);
|
||||
if (!valid_path.ok()) {
|
||||
|
@ -941,7 +939,7 @@ PolicyBuilder& PolicyBuilder::AddDirectory(absl::string_view path, bool is_ro) {
|
|||
PolicyBuilder& PolicyBuilder::AddDirectoryAt(absl::string_view outside,
|
||||
absl::string_view inside,
|
||||
bool is_ro) {
|
||||
EnableNamespaces();
|
||||
EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||
|
||||
auto valid_outside = ValidateAbsolutePath(outside);
|
||||
if (!valid_outside.ok()) {
|
||||
|
@ -969,7 +967,7 @@ PolicyBuilder& PolicyBuilder::AddDirectoryAt(absl::string_view outside,
|
|||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AddTmpfs(absl::string_view inside, size_t size) {
|
||||
EnableNamespaces();
|
||||
EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||
|
||||
if (auto status = mounts_.AddTmpfs(inside, size); !status.ok()) {
|
||||
SetError(absl::InternalError(absl::StrCat("Could not mount tmpfs ", inside,
|
||||
|
@ -979,14 +977,14 @@ PolicyBuilder& PolicyBuilder::AddTmpfs(absl::string_view inside, size_t size) {
|
|||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AllowUnrestrictedNetworking() {
|
||||
EnableNamespaces();
|
||||
EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||
allow_unrestricted_networking_ = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::SetHostname(absl::string_view hostname) {
|
||||
EnableNamespaces();
|
||||
EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||
hostname_ = std::string(hostname);
|
||||
|
||||
return *this;
|
||||
|
@ -1089,7 +1087,7 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyHandlerPolicy() {
|
|||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::SetRootWritable() {
|
||||
EnableNamespaces();
|
||||
EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||
mounts_.SetRootWritable();
|
||||
|
||||
return *this;
|
||||
|
|
|
@ -286,9 +286,6 @@ absl::StatusOr<UnwindResult> StackTracePeer::LaunchLibunwindSandbox(
|
|||
|
||||
absl::StatusOr<std::vector<std::string>> GetStackTrace(const Regs* regs,
|
||||
const Mounts& mounts) {
|
||||
if constexpr (sapi::host_cpu::IsArm64()) {
|
||||
return absl::UnavailableError("Stack traces unavailable on Aarch64");
|
||||
}
|
||||
if (absl::GetFlag(FLAGS_sandbox_disable_all_stack_traces)) {
|
||||
return absl::UnavailableError("Stacktraces disabled");
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ cc_library(
|
|||
"//sandboxed_api/util:raw_logging",
|
||||
"//sandboxed_api/util:status",
|
||||
"//sandboxed_api/util:strerror",
|
||||
"@com_google_absl//absl/cleanup",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@org_gnu_libunwind//:unwind-ptrace-wrapped",
|
||||
|
|
|
@ -30,6 +30,7 @@ add_library(sandbox2_unwind STATIC
|
|||
)
|
||||
add_library(sandbox2::unwind ALIAS sandbox2_unwind)
|
||||
target_link_libraries(sandbox2_unwind PRIVATE
|
||||
absl::cleanup
|
||||
absl::statusor
|
||||
absl::strings
|
||||
sandbox2::comms
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/cleanup/cleanup.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
@ -55,21 +57,20 @@ std::string DemangleSymbol(const std::string& maybe_mangled) {
|
|||
}
|
||||
|
||||
absl::StatusOr<std::vector<uintptr_t>> RunLibUnwind(pid_t pid, int max_frames) {
|
||||
unw_cursor_t cursor;
|
||||
static unw_addr_space_t as =
|
||||
unw_create_addr_space(&_UPT_accessors, 0 /* byte order */);
|
||||
if (as == nullptr) {
|
||||
return absl::InternalError("unw_create_addr_space() failed");
|
||||
}
|
||||
|
||||
std::unique_ptr<struct UPT_info, void (*)(void*)> ui(
|
||||
reinterpret_cast<struct UPT_info*>(_UPT_create(pid)), _UPT_destroy);
|
||||
if (ui == nullptr) {
|
||||
void* context = _UPT_create(pid);
|
||||
if (context == nullptr) {
|
||||
return absl::InternalError("_UPT_create() failed");
|
||||
}
|
||||
absl::Cleanup context_cleanup = [&context] { _UPT_destroy(context); };
|
||||
|
||||
int rc = unw_init_remote(&cursor, as, ui.get());
|
||||
if (rc < 0) {
|
||||
unw_cursor_t cursor;
|
||||
if (int rc = unw_init_remote(&cursor, as, context); rc < 0) {
|
||||
// Could be UNW_EINVAL (8), UNW_EUNSPEC (1) or UNW_EBADREG (3).
|
||||
return absl::InternalError(
|
||||
absl::StrCat("unw_init_remote() failed with error ", rc));
|
||||
|
@ -78,7 +79,7 @@ absl::StatusOr<std::vector<uintptr_t>> RunLibUnwind(pid_t pid, int max_frames) {
|
|||
std::vector<uintptr_t> ips;
|
||||
for (int i = 0; i < max_frames; ++i) {
|
||||
unw_word_t ip;
|
||||
rc = unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||
int rc = unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||
if (rc < 0) {
|
||||
// Could be UNW_EUNSPEC or UNW_EBADREG.
|
||||
SAPI_RAW_LOG(WARNING, "unw_get_reg() failed with error %d", rc);
|
||||
|
@ -176,8 +177,10 @@ absl::StatusOr<SymbolMap> LoadSymbolsMap(pid_t pid) {
|
|||
|
||||
for (const ElfFile::Symbol& symbol : elf->symbols()) {
|
||||
if (elf->position_independent()) {
|
||||
if (symbol.address < entry.end - entry.start) {
|
||||
addr_to_symbol[symbol.address + entry.start] = symbol.name;
|
||||
if (symbol.address >= entry.pgoff &&
|
||||
symbol.address - entry.pgoff < entry.end - entry.start) {
|
||||
addr_to_symbol[symbol.address + entry.start - entry.pgoff] =
|
||||
symbol.name;
|
||||
}
|
||||
} else {
|
||||
if (symbol.address >= entry.start && symbol.address < entry.end) {
|
||||
|
|
|
@ -26,13 +26,14 @@
|
|||
#include "sandboxed_api/util/file_helpers.h"
|
||||
#include "sandboxed_api/util/status_matchers.h"
|
||||
|
||||
extern "C" void ExportedFunctionName() {
|
||||
extern "C" void ExportedFunction() {
|
||||
// Don't do anything - used to generate a symbol.
|
||||
}
|
||||
|
||||
namespace file = ::sapi::file;
|
||||
using ::sapi::GetTestSourcePath;
|
||||
using ::sapi::IsOk;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
using ::testing::IsTrue;
|
||||
using ::testing::Ne;
|
||||
|
@ -65,19 +66,20 @@ TEST(MinielfTest, SymbolResolutionWorks) {
|
|||
ParseProcMaps(maps_buffer));
|
||||
|
||||
// Find maps entry that covers this entry.
|
||||
uint64_t function_address = reinterpret_cast<uint64_t>(ExportedFunctionName);
|
||||
auto function_entry =
|
||||
uint64_t function_address = reinterpret_cast<uint64_t>(&ExportedFunction);
|
||||
auto entry =
|
||||
absl::c_find_if(maps, [function_address](const MapsEntry& entry) {
|
||||
return entry.start <= function_address && entry.end > function_address;
|
||||
});
|
||||
ASSERT_THAT(function_entry, Ne(maps.end()));
|
||||
function_address -= function_entry->start;
|
||||
ASSERT_THAT(entry, Ne(maps.end()));
|
||||
|
||||
auto function_symbol =
|
||||
absl::c_find_if(elf.symbols(), [](const ElfFile::Symbol& symbol) {
|
||||
return symbol.name == "ExportedFunctionName";
|
||||
return symbol.name == "ExportedFunction";
|
||||
});
|
||||
ASSERT_THAT(function_symbol, Ne(elf.symbols().end()));
|
||||
|
||||
function_address -= entry->start - entry->pgoff;
|
||||
EXPECT_THAT(function_symbol->address, Eq(function_address));
|
||||
}
|
||||
|
||||
|
@ -86,8 +88,7 @@ TEST(MinielfTest, ImportedLibraries) {
|
|||
ElfFile elf, ElfFile::ParseFromFile(
|
||||
GetTestSourcePath("sandbox2/util/testdata/hello_world"),
|
||||
ElfFile::kLoadImportedLibraries));
|
||||
std::vector<std::string> imported_libraries = {"libc.so.6"};
|
||||
EXPECT_THAT(elf.imported_libraries(), Eq(imported_libraries));
|
||||
EXPECT_THAT(elf.imported_libraries(), ElementsAre("libc.so.6"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -31,8 +31,11 @@ void SaveStatusToProto(const absl::Status& status, StatusProto* out) {
|
|||
absl::Status MakeStatusFromProto(const StatusProto& proto) {
|
||||
absl::Status status(static_cast<absl::StatusCode>(proto.code()),
|
||||
proto.message());
|
||||
for (const auto& [type_key, payload] : proto.payloads()) {
|
||||
status.SetPayload(type_key, absl::Cord(payload));
|
||||
// Note: Using C++17 structured bindings instead of `entry` crashes Clang 6.0
|
||||
// on Ubuntu 18.04 (bionic).
|
||||
for (const auto& entry : proto.payloads()) {
|
||||
status.SetPayload(/*type_url=*/entry.first,
|
||||
/*payload=*/absl::Cord(entry.second));
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user