1 /* Backport - Bring New Fixes to old Androids
2 * Copyright (C) 2013 Jay Freeman (saurik)
5 /* GNU Lesser General Public License, Version 3 {{{ */
7 * Substrate is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
12 * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Substrate. If not, see <http://www.gnu.org/licenses/>.
22 package com
.saurik
.backport
;
24 import java
.lang
.reflect
.Field
;
25 import java
.lang
.reflect
.Method
;
27 import java
.util
.LinkedHashMap
;
29 import java
.util
.jar
.JarFile
;
31 import java
.util
.zip
.ZipEntry
;
32 import java
.util
.zip
.ZipException
;
33 import java
.util
.zip
.ZipFile
;
35 import android
.util
.Log
;
37 import com
.saurik
.substrate
.MS
;
40 private static class WrongException
41 extends RuntimeException
43 public WrongException(Throwable cause
) {
48 public static void initialize() {
49 MS
.hookClassLoad("java.util.zip.ZipFile", new MS
.ClassLoadHook() {
50 public void classLoaded(Class
<?
> ZipFile$
) {
51 Field entries
= null; {
52 if (entries
== null) try {
53 entries
= ZipFile$
.getDeclaredField("entries");
54 } catch (NoSuchFieldException e
) {}
56 if (entries
== null) try {
57 entries
= ZipFile$
.getDeclaredField("mEntries");
58 } catch (NoSuchFieldException e
) {}
63 final Field ZipFile$entries
= entries
;
64 ZipFile$entries
.setAccessible(true);
66 final Method ZipFile$readCentralDir
; try {
67 ZipFile$readCentralDir
= ZipFile$
.getDeclaredMethod("readCentralDir");
68 } catch (NoSuchMethodException e
) {
69 Log
.e("Backport", "ZipFile$readCentralDir", e
);
73 MS
.hookMethod(ZipFile$
, ZipFile$readCentralDir
,
74 new MS
.MethodAlteration
<ZipFile
, Void
>() {
75 public Void
invoked(ZipFile thiz
, Object
... args
)
78 ZipFile$entries
.set(thiz
, new LinkedHashMap
<String
, ZipEntry
>() {
79 public ZipEntry
put(String key
, ZipEntry value
) {
80 if (super.put(key
, value
) != null)
81 throw new WrongException(new ZipException("Duplicate entry name: " + key
));
87 return invoke(thiz
, args
);
88 } catch (WrongException wrong
) {
89 throw wrong
.getCause();