Esempio n. 1
0
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());
}
Esempio n. 2
0
static void *
extractBuf(const char * path, Zip *zip)
{
  Zip::Stream s;
  if (!zip->GetStream(path, &s))
    return NULL;

  void * buf = malloc(s.GetUncompressedSize());
  if (buf == (void *)-1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't alloc decompression buffer for %s", path);
    return NULL;
  }
  if (s.GetType() == Zip::Stream::DEFLATE)
    extractLib(s, buf);
  else
    memcpy(buf, s.GetBuffer(), s.GetUncompressedSize());

  return buf;
}
Esempio n. 3
0
static void *
extractBuf(const char * path, Zip *zip)
{
    Zip::Stream s;
    if (!zip->GetStream(path, &s))
        return NULL;

    // allocate space for a trailing null byte
    void * buf = malloc(s.GetUncompressedSize() + 1);
    if (buf == (void *)-1) {
        __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't alloc decompression buffer for %s", path);
        return NULL;
    }
    if (s.GetType() == Zip::Stream::DEFLATE)
        extractLib(s, buf);
    else
        memcpy(buf, s.GetBuffer(), s.GetUncompressedSize());

    // null terminate it
    ((unsigned char*) buf)[s.GetUncompressedSize()] = 0;

    return buf;
}
Esempio n. 4
0
static void
extractFile(const char * path, Zip::Stream &s)
{
  uint32_t size = s.GetUncompressedSize();

  struct stat status;
  if (!stat(path, &status) &&
      status.st_size == size &&
      apk_mtime < status.st_mtime)
    return;

  int fd = open(path, O_CREAT | O_NOATIME | O_TRUNC | O_RDWR, S_IRWXU);
  if (fd == -1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open %s to decompress library", path);
    return;
  }

  if (ftruncate(fd, size) == -1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't ftruncate %s to decompress library", path);
    close(fd);
    return;
  }

  void * buf = mmap(NULL, size, PROT_READ | PROT_WRITE,
                    MAP_SHARED, fd, 0);
  if (buf == (void *)-1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
    close(fd);
    return;
  }

  z_stream strm = {
    next_in: (Bytef *)s.GetBuffer(),
    avail_in: s.GetSize(),
    total_in: 0,

    next_out: (Bytef *)buf,
    avail_out: size,
    total_out: 0
  };

  int ret;
  ret = inflateInit2(&strm, -MAX_WBITS);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateInit failed: %s", strm.msg);

  if (inflate(&strm, Z_FINISH) != Z_STREAM_END)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflate failed: %s", strm.msg);

  if (strm.total_out != size)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "extracted %d, expected %d!", strm.total_out, size);

  ret = inflateEnd(&strm);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateEnd failed: %s", strm.msg);

  close(fd);
#ifdef ANDROID_ARM_LINKER
  /* We just extracted data that is going to be executed in the future.
   * We thus need to ensure Instruction and Data cache coherency. */
  cacheflush((unsigned) buf, (unsigned) buf + size, 0);
#endif
  munmap(buf, size);
}