• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
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  * http://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 
16 #include "app_log_wrapper.h"
17 #include "bundle_error.h"
18 #include "zip_ffi.h"
19 #include "zlib.h"
20 
21 using namespace OHOS::CJSystemapi::BundleManager;
22 
23 namespace OHOS {
24 namespace AppExecFwk {
25 namespace LIBZIP {
ZlibBusinessError(int32_t errCode)26 static inline ErrCode ZlibBusinessError(int32_t errCode)
27 {
28     if (errCode == Z_STREAM_ERROR) {
29         return ERR_ZLIB_ZSTREAM_ERROR;
30     } else if (errCode == Z_MEM_ERROR) {
31         return ERR_ZLIB_MEMORY_ALLOC_FAILED;
32     } else if (errCode == Z_BUF_ERROR) {
33         return ERR_ZLIB_BUFFER_ERROR;
34     } else {
35         return ERR_ZLIB_INTERNAL_STRUCT_ERROR;
36     }
37 }
38 
39 struct CjGZipEntity {
40     int32_t Dopen(int32_t fd, const char* mode);
41     int32_t Open(const char* path, const char* mode);
42     int32_t Eof();
43     int32_t Close(int32_t* errCode);
44     int64_t Write(uint8_t* buf, int64_t len, int32_t* errCode);
45     int64_t Read(uint8_t* buf, int64_t len, int32_t* errCode);
46     int32_t Puts(const char* cstr, int32_t* errCode);
47     char* GzGets(uint8_t* buf, int64_t len, int32_t* errCode);
48 
49     gzFile gzs = {};
50 };
51 
Dopen(int32_t fd,const char * mode)52 int32_t CjGZipEntity::Dopen(int32_t fd, const char* mode)
53 {
54     gzs = gzdopen(fd, mode);
55     if (gzs == nullptr) {
56         APP_LOGE("gzdopen return nullptr");
57         return ERR_ZLIB_NO_SUCH_FILE_OR_MODE_ERROR;
58     }
59     return 0;
60 }
61 
Open(const char * path,const char * mode)62 int32_t CjGZipEntity::Open(const char* path, const char* mode)
63 {
64 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
65     gzs = gzopen64(path, mode);
66 #else
67     gzs = gzopen(path, mode);
68 #endif
69     if (gzs == nullptr) {
70         APP_LOGE("gzopen return nullptr");
71         return ERR_ZLIB_NO_SUCH_FILE_OR_MODE_ERROR;
72     }
73     return 0;
74 }
75 
Eof()76 int32_t CjGZipEntity::Eof()
77 {
78     return gzeof(gzs);
79 }
80 
Close(int32_t * errCode)81 int32_t CjGZipEntity::Close(int32_t* errCode)
82 {
83     auto ret = gzclose(gzs);
84     if (ret < 0) {
85         APP_LOGE("gzclose return failed, code: %{public}d", ret);
86         *errCode = ZlibBusinessError(ret);
87     }
88     return ret;
89 }
90 
Write(uint8_t * buf,int64_t len,int32_t * errCode)91 int64_t CjGZipEntity::Write(uint8_t* buf, int64_t len, int32_t* errCode)
92 {
93     int64_t writeLen = gzwrite(gzs, buf, static_cast<unsigned int>(len));
94     if (writeLen <= 0) {
95         APP_LOGE("gzwrite return failed, code: %{public}d", static_cast<int32_t>(writeLen));
96         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
97     }
98     return writeLen;
99 }
100 
Read(uint8_t * buf,int64_t len,int32_t * errCode)101 int64_t CjGZipEntity::Read(uint8_t* buf, int64_t len, int32_t* errCode)
102 {
103     int64_t readLen = gzread(gzs, reinterpret_cast<void*>(buf), static_cast<unsigned int>(len));
104     if (readLen < 0) {
105         APP_LOGE("gzread return failed, code: %{public}d", static_cast<int32_t>(readLen));
106         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
107     }
108     return readLen;
109 }
110 
Puts(const char * cstr,int32_t * errCode)111 int32_t CjGZipEntity::Puts(const char* cstr, int32_t* errCode)
112 {
113     int64_t putLen = gzputs(gzs, cstr);
114     if (putLen < 0) {
115         APP_LOGE("gzputs return failed, code: %{public}d", static_cast<int32_t>(putLen));
116         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
117     }
118     return putLen;
119 }
120 
GzGets(uint8_t * buf,int64_t len,int32_t * errCode)121 char* CjGZipEntity::GzGets(uint8_t* buf, int64_t len, int32_t* errCode)
122 {
123     auto nullTerminatedString = gzgets(gzs, reinterpret_cast<char*>(buf), static_cast<int>(len));
124     if (!nullTerminatedString) {
125         APP_LOGE("gzgets return failed");
126         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
127     }
128     return nullTerminatedString;
129 }
130 
131 extern "C" {
FfiBundleManagerGZipInstCreate()132 FFI_EXPORT void* FfiBundleManagerGZipInstCreate()
133 {
134     return new CjGZipEntity();
135 }
136 
FfiBundleManagerGZipInstDestroy(void * ffiInst)137 FFI_EXPORT void FfiBundleManagerGZipInstDestroy(void* ffiInst)
138 {
139     delete static_cast<CjGZipEntity*>(ffiInst);
140 }
141 
FfiBundleManagerGZipDopen(void * ffiInst,int32_t fd,const char * mode,int32_t * errCode)142 FFI_EXPORT void FfiBundleManagerGZipDopen(void* ffiInst, int32_t fd, const char* mode, int32_t* errCode)
143 {
144     *errCode = 0;
145     if (ffiInst == nullptr || mode == nullptr) {
146         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
147         APP_LOGE("FfiBundleManagerGZipDopen param check failed");
148         return;
149     }
150     auto entity = static_cast<CjGZipEntity*>(ffiInst);
151     *errCode = entity->Dopen(fd, mode);
152     return;
153 }
154 
FfiBundleManagerGZipOpen(void * ffiInst,const char * path,const char * mode,int32_t * errCode)155 FFI_EXPORT void FfiBundleManagerGZipOpen(void* ffiInst, const char* path, const char* mode, int32_t* errCode)
156 {
157     *errCode = 0;
158     if (ffiInst == nullptr || path == nullptr || mode == nullptr) {
159         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
160         APP_LOGE("FfiBundleManagerGZipOpen param check failed");
161         return;
162     }
163     auto entity = static_cast<CjGZipEntity*>(ffiInst);
164     *errCode = entity->Open(path, mode);
165     return;
166 }
167 
FfiBundleManagerGZipEof(void * ffiInst,int32_t * errCode)168 FFI_EXPORT int32_t FfiBundleManagerGZipEof(void* ffiInst, int32_t* errCode)
169 {
170     *errCode = 0;
171     if (ffiInst == nullptr) {
172         APP_LOGE("FfiBundleManagerGZipEof param check failed");
173         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
174         return 0;
175     }
176     auto entity = static_cast<CjGZipEntity*>(ffiInst);
177     return entity->Eof();
178 }
179 
FfiBundleManagerGZipClose(void * ffiInst,int32_t * errCode)180 FFI_EXPORT int32_t FfiBundleManagerGZipClose(void* ffiInst, int32_t* errCode)
181 {
182     *errCode = 0;
183     if (ffiInst == nullptr) {
184         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
185         APP_LOGE("FfiBundleManagerGZipClose param check failed");
186         return 0;
187     }
188     auto entity = static_cast<CjGZipEntity*>(ffiInst);
189     return entity->Close(errCode);
190 }
191 
FfiBundleManagerGZipWrite(void * ffiInst,uint8_t * buf,int64_t len,int32_t * errCode)192 FFI_EXPORT int64_t FfiBundleManagerGZipWrite(void* ffiInst, uint8_t* buf, int64_t len, int32_t* errCode)
193 {
194     *errCode = 0;
195     if (ffiInst == nullptr || buf == nullptr || len <= 0) {
196         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
197         APP_LOGE("FfiBundleManagerGZipWrite param check failed");
198         return 0;
199     }
200     auto entity = static_cast<CjGZipEntity*>(ffiInst);
201     return entity->Write(buf, len, errCode);
202 }
203 
FfiBundleManagerGZipRead(void * ffiInst,uint8_t * buf,int64_t len,int32_t * errCode)204 FFI_EXPORT int64_t FfiBundleManagerGZipRead(void* ffiInst, uint8_t* buf, int64_t len, int32_t* errCode)
205 {
206     *errCode = 0;
207     if (ffiInst == nullptr || buf == nullptr || len <= 0) {
208         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
209         APP_LOGE("FfiBundleManagerGZipRead param check failed");
210         return 0;
211     }
212     auto entity = static_cast<CjGZipEntity*>(ffiInst);
213     return entity->Read(buf, len, errCode);
214 }
215 
FfiBundleManagerGZipPuts(void * ffiInst,const char * cstr,int32_t * errCode)216 FFI_EXPORT int32_t FfiBundleManagerGZipPuts(void* ffiInst, const char* cstr, int32_t* errCode)
217 {
218     *errCode = 0;
219     if (ffiInst == nullptr || cstr == nullptr) {
220         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
221         APP_LOGE("FfiBundleManagerGZipPuts param check failed");
222         return 0;
223     }
224     auto entity = static_cast<CjGZipEntity*>(ffiInst);
225     return entity->Puts(cstr, errCode);
226 }
227 
FfiBundleManagerGZipGets(void * ffiInst,uint8_t * buf,int64_t len,int32_t * errCode)228 FFI_EXPORT char* FfiBundleManagerGZipGets(void* ffiInst, uint8_t* buf, int64_t len, int32_t* errCode)
229 {
230     *errCode = 0;
231     if (ffiInst == nullptr || buf == nullptr || len <= 0) {
232         *errCode = ERR_ZLIB_INTERNAL_STRUCT_ERROR;
233         APP_LOGE("FfiBundleManagerGZipGets param check failed");
234         return 0;
235     }
236     auto entity = static_cast<CjGZipEntity*>(ffiInst);
237     return entity->GzGets(buf, len, errCode);
238 }
239 } // extern "C"
240 } // namespace LIBZIP
241 } // namespace AppExecFwk
242 } // namespace OHOS
243