1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "contrib/brotli/utils/utils_brotli_dec.h"
16
17 #include <fstream>
18 #include <string>
19
20 #include "contrib/brotli/sandboxed.h"
21 #include "contrib/brotli/utils/utils_brotli.h"
22
InitStructs()23 absl::Status BrotliDecoder::InitStructs() {
24 SAPI_ASSIGN_OR_RETURN(
25 BrotliDecoderState * state,
26 api_.BrotliDecoderCreateInstance(nullptr, nullptr, nullptr));
27
28 state_.SetRemote(state);
29
30 return absl::OkStatus();
31 }
32
~BrotliDecoder()33 BrotliDecoder::~BrotliDecoder() {
34 if (state_.GetRemote() != nullptr) {
35 api_.BrotliDecoderDestroyInstance(state_.PtrNone()).IgnoreError();
36 }
37 }
38
IsInit()39 bool BrotliDecoder::IsInit() {
40 if (state_.GetRemote() == nullptr) {
41 return false;
42 }
43
44 return true;
45 }
46
CheckIsInit()47 absl::Status BrotliDecoder::CheckIsInit() {
48 if (!IsInit()) {
49 return absl::UnavailableError("The decoder is not initialized");
50 }
51
52 return absl::OkStatus();
53 }
54
SetParameter(enum BrotliDecoderParameter param,uint32_t value)55 absl::Status BrotliDecoder::SetParameter(enum BrotliDecoderParameter param,
56 uint32_t value) {
57 SAPI_RETURN_IF_ERROR(CheckIsInit());
58
59 SAPI_ASSIGN_OR_RETURN(
60 int ret, api_.BrotliDecoderSetParameter(state_.PtrNone(), param, value));
61 if (!ret) {
62 return absl::UnavailableError("Unable to set parameter");
63 }
64
65 return absl::OkStatus();
66 }
67
Decompress(std::vector<uint8_t> & buf_in)68 absl::StatusOr<BrotliDecoderResult> BrotliDecoder::Decompress(
69 std::vector<uint8_t>& buf_in) {
70 SAPI_RETURN_IF_ERROR(CheckIsInit());
71
72 sapi::v::Array<uint8_t> sapi_buf_in(buf_in.data(), buf_in.size());
73 sapi::v::IntBase<size_t> sapi_size_in(buf_in.size());
74
75 // BrotliDecoderCompress requires a pointer to a pointer,
76 // as function moves to pointer to indicate how much data
77 // was compressed.
78 // In this case we compress whole buffer so we don't use it
79 // but we still have to allocate buffer remotely and gets
80 // a pointer.
81 SAPI_RETURN_IF_ERROR(sandbox_->Allocate(&sapi_buf_in));
82 SAPI_RETURN_IF_ERROR(sandbox_->TransferToSandboxee(&sapi_buf_in));
83 sapi::v::GenericPtr sapi_opaque_buf_in(sapi_buf_in.GetRemote());
84
85 sapi::v::IntBase<size_t> sapi_avilable_out(0);
86
87 SAPI_ASSIGN_OR_RETURN(BrotliDecoderResult ret,
88 api_.BrotliDecoderDecompressStream(
89 state_.PtrNone(), sapi_size_in.PtrBefore(),
90 sapi_opaque_buf_in.PtrBefore(),
91 sapi_avilable_out.PtrBefore(), nullptr, nullptr));
92
93 // Ignore output error, as we didn't provide any buffer.
94 if (ret == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
95 ret = BROTLI_DECODER_RESULT_SUCCESS;
96 }
97
98 return ret;
99 }
100
TakeOutput()101 absl::StatusOr<std::vector<uint8_t>> BrotliDecoder::TakeOutput() {
102 SAPI_RETURN_IF_ERROR(CheckIsInit());
103
104 sapi::v::IntBase<size_t> sapi_size_out(0);
105
106 SAPI_ASSIGN_OR_RETURN(
107 uint8_t * sapi_out_buf_ptr,
108 api_.BrotliDecoderTakeOutput(state_.PtrNone(), sapi_size_out.PtrAfter()));
109 if (sapi_out_buf_ptr == nullptr || sapi_size_out.GetValue() == 0) {
110 return std::vector<uint8_t>(0);
111 }
112 if (sapi_size_out.GetValue() > kFileMaxSize) {
113 return absl::UnavailableError("Output to large");
114 }
115
116 std::vector<uint8_t> buf_out(sapi_size_out.GetValue());
117 sapi::v::Array<uint8_t> sapi_buf_out(buf_out.data(), buf_out.size());
118 sapi_buf_out.SetRemote(sapi_out_buf_ptr);
119
120 SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&sapi_buf_out));
121
122 return buf_out;
123 }
124