18a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak/* 28a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * Licensed to the Apache Software Foundation (ASF) under one or more 38a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * contributor license agreements. See the NOTICE file distributed with 48a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * this work for additional information regarding copyright ownership. 58a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * The ASF licenses this file to You under the Apache License, Version 2.0 68a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * (the "License"); you may not use this file except in compliance with 78a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * the License. You may obtain a copy of the License at 88a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * 98a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * http://www.apache.org/licenses/LICENSE-2.0 108a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * 118a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * Unless required by applicable law or agreed to in writing, software 128a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * distributed under the License is distributed on an "AS IS" BASIS, 138a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * See the License for the specific language governing permissions and 158a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak * limitations under the License. 168a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak */ 178a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 188a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#define LOG_TAG "StrictJarFile" 198a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 208a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include <memory> 218a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include <string> 228a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 238a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include "JNIHelp.h" 248a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include "JniConstants.h" 258a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include "ScopedLocalRef.h" 268a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include "ScopedUtfChars.h" 278a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include "jni.h" 288a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include "ziparchive/zip_archive.h" 298a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak#include "cutils/log.h" 308a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 318a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniaknamespace android { 328a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 338a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak// The method ID for ZipEntry.<init>(String,String,JJJIII[BJJ) 348a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic jmethodID zipEntryCtor; 358a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 368a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic void throwIoException(JNIEnv* env, const int32_t errorCode) { 378a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode)); 388a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 398a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 408a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) { 418a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return env->NewObject(JniConstants::zipEntryClass, 428a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak zipEntryCtor, 438a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak entryName, 448a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak NULL, // comment 458a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak static_cast<jlong>(entry.crc32), 468a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak static_cast<jlong>(entry.compressed_length), 478a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak static_cast<jlong>(entry.uncompressed_length), 488a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak static_cast<jint>(entry.method), 498a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak static_cast<jint>(0), // time 508a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak NULL, // byte[] extra 518a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak static_cast<jlong>(entry.offset)); 528a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 538a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 548a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileName) { 558a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ScopedUtfChars fileChars(env, fileName); 568a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (fileChars.c_str() == NULL) { 578a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return static_cast<jlong>(-1); 588a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 598a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 608a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ZipArchiveHandle handle; 618a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak int32_t error = OpenArchive(fileChars.c_str(), &handle); 628a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (error) { 638a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak CloseArchive(handle); 648a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak throwIoException(env, error); 658a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return static_cast<jlong>(-1); 668a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 678a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 688a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return reinterpret_cast<jlong>(handle); 698a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 708a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 718a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakclass IterationHandle { 728a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak public: 738a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak IterationHandle() : 748a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak cookie_(NULL) { 758a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 768a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 778a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak void** CookieAddress() { 788a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return &cookie_; 798a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 808a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 818a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ~IterationHandle() { 828a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak EndIteration(cookie_); 838a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 848a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 858a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak private: 868a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak void* cookie_; 878a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak}; 888a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 898a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 908a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nativeHandle, 918a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak jstring prefix) { 928a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ScopedUtfChars prefixChars(env, prefix); 938a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (prefixChars.c_str() == NULL) { 948a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return static_cast<jlong>(-1); 958a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 968a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 978a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak IterationHandle* handle = new IterationHandle(); 988a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak int32_t error = 0; 998a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (prefixChars.size() == 0) { 1008a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle), 1018a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak handle->CookieAddress(), NULL, NULL); 1028a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } else { 1038a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ZipString entry_name(prefixChars.c_str()); 1048a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle), 1058a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak handle->CookieAddress(), &entry_name, NULL); 1068a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 1078a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1088a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (error) { 1098a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak throwIoException(env, error); 1108a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return static_cast<jlong>(-1); 1118a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 1128a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1138a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return reinterpret_cast<jlong>(handle); 1148a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 1158a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1168a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) { 1178a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ZipEntry data; 1188a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ZipString entryName; 1198a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1208a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak IterationHandle* handle = reinterpret_cast<IterationHandle*>(iterationHandle); 1218a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak const int32_t error = Next(*handle->CookieAddress(), &data, &entryName); 1228a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (error) { 1238a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak delete handle; 1248a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return NULL; 1258a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 1268a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1278a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak std::unique_ptr<char[]> entryNameCString(new char[entryName.name_length + 1]); 1288a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak memcpy(entryNameCString.get(), entryName.name, entryName.name_length); 1298a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak entryNameCString[entryName.name_length] = '\0'; 1308a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ScopedLocalRef<jstring> entryNameString(env, env->NewStringUTF(entryNameCString.get())); 1318a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1328a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return newZipEntry(env, data, entryNameString.get()); 1338a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 1348a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1358a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle, 1368a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak jstring entryName) { 1378a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ScopedUtfChars entryNameChars(env, entryName); 1388a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (entryNameChars.c_str() == NULL) { 1398a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return NULL; 1408a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 1418a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1428a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ZipEntry data; 1438a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle), 1448a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak ZipString(entryNameChars.c_str()), &data); 1458a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak if (error) { 1468a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return NULL; 1478a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak } 1488a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1498a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak return newZipEntry(env, data, entryName); 1508a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 1518a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1528a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) { 1538a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak CloseArchive(reinterpret_cast<ZipArchiveHandle>(nativeHandle)); 1548a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 1558a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1568a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniakstatic JNINativeMethod gMethods[] = { 1578a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak NATIVE_METHOD(StrictJarFile, nativeOpenJarFile, "(Ljava/lang/String;)J"), 1588a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak NATIVE_METHOD(StrictJarFile, nativeStartIteration, "(JLjava/lang/String;)J"), 1598a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak NATIVE_METHOD(StrictJarFile, nativeNextEntry, "(J)Ljava/util/zip/ZipEntry;"), 1608a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak NATIVE_METHOD(StrictJarFile, nativeFindEntry, "(JLjava/lang/String;)Ljava/util/zip/ZipEntry;"), 1618a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak NATIVE_METHOD(StrictJarFile, nativeClose, "(J)V"), 1628a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak}; 1638a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 164faa1033dc7d6b1ea6c17a483e586eaa167d154f9Andreas Gampeint register_android_util_jar_StrictJarFile(JNIEnv* env) { 1658a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak jniRegisterNativeMethods(env, "android/util/jar/StrictJarFile", gMethods, NELEM(gMethods)); 1668a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1678a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak zipEntryCtor = env->GetMethodID(JniConstants::zipEntryClass, "<init>", 1688a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak "(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V"); 1698a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak LOG_ALWAYS_FATAL_IF(zipEntryCtor == NULL, "Unable to find ZipEntry.<init>"); 170faa1033dc7d6b1ea6c17a483e586eaa167d154f9Andreas Gampe 171faa1033dc7d6b1ea6c17a483e586eaa167d154f9Andreas Gampe return 0; 1728a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak} 1738a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak 1748a7c1606d88873c5a1b5764c16cb046b6f2275b2Przemyslaw Szczepaniak}; // namespace android 175