xref: /aosp_15_r20/external/sandboxed-api/contrib/brotli/utils/utils_brotli_dec.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
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(&null_ptr_, &null_ptr_, &null_ptr_));
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(
88       BrotliDecoderResult ret,
89       api_.BrotliDecoderDecompressStream(
90           state_.PtrNone(), sapi_size_in.PtrBefore(),
91           sapi_opaque_buf_in.PtrBefore(), sapi_avilable_out.PtrBefore(),
92           &null_ptr_, &null_ptr_));
93 
94   // Ignore output error, as we didn't provide any buffer.
95   if (ret == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
96     ret = BROTLI_DECODER_RESULT_SUCCESS;
97   }
98 
99   return ret;
100 }
101 
TakeOutput()102 absl::StatusOr<std::vector<uint8_t>> BrotliDecoder::TakeOutput() {
103   SAPI_RETURN_IF_ERROR(CheckIsInit());
104 
105   sapi::v::IntBase<size_t> sapi_size_out(0);
106 
107   SAPI_ASSIGN_OR_RETURN(
108       uint8_t * sapi_out_buf_ptr,
109       api_.BrotliDecoderTakeOutput(state_.PtrNone(), sapi_size_out.PtrAfter()));
110   if (sapi_out_buf_ptr == nullptr || sapi_size_out.GetValue() == 0) {
111     return std::vector<uint8_t>(0);
112   }
113   if (sapi_size_out.GetValue() > kFileMaxSize) {
114     return absl::UnavailableError("Output to large");
115   }
116 
117   std::vector<uint8_t> buf_out(sapi_size_out.GetValue());
118   sapi::v::Array<uint8_t> sapi_buf_out(buf_out.data(), buf_out.size());
119   sapi_buf_out.SetRemote(sapi_out_buf_ptr);
120 
121   SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&sapi_buf_out));
122 
123   return buf_out;
124 }
125