1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <jni.h>
#include <stdlib.h>
#include <fcntl.h>
#include "APKOpen.h"
#include "Zip.h"
#include "mozilla/RefPtr.h"
#ifdef MOZ_CRASHREPORTER
# include "minidump-analyzer.h"
#endif
extern "C" __attribute__((visibility("default"))) void MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_GeckoLoader_putenv(JNIEnv* jenv, jclass,
jstring map) {
const char* str;
// XXX: java doesn't give us true UTF8, we should figure out something
// better to do here
str = jenv->GetStringUTFChars(map, nullptr);
if (str == nullptr) return;
putenv(strdup(str));
jenv->ReleaseStringUTFChars(map, str);
}
extern "C" APKOPEN_EXPORT jboolean MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_GeckoLoader_verifyCRCs(JNIEnv* jenv, jclass,
jstring jApkName) {
const char* str;
// XXX: java doesn't give us true UTF8, we should figure out something
// better to do here
str = jenv->GetStringUTFChars(jApkName, nullptr);
if (str == nullptr) {
return false;
}
RefPtr<Zip> zip = Zip::Create(str);
const bool valid = zip->VerifyCRCs();
jenv->ReleaseStringUTFChars(jApkName, str);
return jboolean(valid);
}
extern "C" __attribute__((visibility("default"))) jobject MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_DirectBufferAllocator_nativeAllocateDirectBuffer(
JNIEnv* jenv, jclass, jlong size) {
jobject buffer = nullptr;
void* mem = malloc(size);
if (mem) {
buffer = jenv->NewDirectByteBuffer(mem, size);
if (!buffer) free(mem);
}
return buffer;
}
extern "C" __attribute__((visibility("default"))) void MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_DirectBufferAllocator_nativeFreeDirectBuffer(
JNIEnv* jenv, jclass, jobject buf) {
free(jenv->GetDirectBufferAddress(buf));
}
extern "C" __attribute__((visibility("default"))) jlong MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_NativeZip_getZip(JNIEnv* jenv, jclass,
jstring path) {
const char* str;
str = jenv->GetStringUTFChars(path, nullptr);
if (!str || !*str) {
if (str) jenv->ReleaseStringUTFChars(path, str);
JNI_Throw(jenv, "java/lang/IllegalArgumentException", "Invalid path");
return 0;
}
RefPtr<Zip> zip = ZipCollection::GetZip(str);
jenv->ReleaseStringUTFChars(path, str);
if (!zip) {
JNI_Throw(jenv, "java/lang/IllegalArgumentException",
"Invalid path or invalid zip");
return 0;
}
return reinterpret_cast<jlong>(zip.forget().take());
}
extern "C" __attribute__((visibility("default"))) jlong MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_NativeZip_getZipFromByteBuffer(JNIEnv* jenv,
jclass,
jobject buffer) {
void* buf = jenv->GetDirectBufferAddress(buffer);
size_t size = jenv->GetDirectBufferCapacity(buffer);
RefPtr<Zip> zip = Zip::Create(buf, size);
if (!zip) {
JNI_Throw(jenv, "java/lang/IllegalArgumentException", "Invalid zip");
return 0;
}
return reinterpret_cast<jlong>(zip.forget().take());
}
extern "C" __attribute__((visibility("default"))) void MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_NativeZip__1release(JNIEnv* jenv, jclass,
jlong obj) {
Zip* zip = (Zip*)obj;
zip->Release();
}
extern "C" __attribute__((visibility("default"))) jobject MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_NativeZip__1getInputStream(JNIEnv* jenv,
jobject jzip,
jlong obj,
jstring path) {
Zip* zip = (Zip*)obj;
const char* str;
str = jenv->GetStringUTFChars(path, nullptr);
Zip::Stream stream;
bool res = zip->GetStream(str, &stream);
jenv->ReleaseStringUTFChars(path, str);
if (!res) {
return nullptr;
}
jobject buf = jenv->NewDirectByteBuffer(const_cast<void*>(stream.GetBuffer()),
stream.GetSize());
if (!buf) {
JNI_Throw(jenv, "java/lang/RuntimeException",
"Failed to create ByteBuffer");
return nullptr;
}
jclass nativeZip = jenv->GetObjectClass(jzip);
jmethodID method =
jenv->GetMethodID(nativeZip, "createInputStream",
"(Ljava/nio/ByteBuffer;I)Ljava/io/InputStream;");
// Since this function is only expected to be called from Java, it is safe
// to skip exception checking for the method call below, as long as no
// other Native -> Java call doesn't happen before returning to Java.
return jenv->CallObjectMethod(jzip, method, buf, (jint)stream.GetType());
}
#ifdef MOZ_CRASHREPORTER
extern "C" __attribute__((visibility("default"))) jboolean MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_MinidumpAnalyzer_GenerateStacks(
JNIEnv* jenv, jclass, jstring minidumpPath, jboolean fullStacks) {
const char* str;
str = jenv->GetStringUTFChars(minidumpPath, nullptr);
bool res = CrashReporter::GenerateStacks(str, fullStacks);
jenv->ReleaseStringUTFChars(minidumpPath, str);
return res;
}
#endif // MOZ_CRASHREPORTER
|