DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (c073e3faa76e)

VCS Links

Line Code
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: 4; 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