@hot-updater/react-native 1.0.7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HotUpdater.podspec +14 -2
- package/Package.swift +24 -3
- package/android/build.gradle +2 -6
- package/android/hot-updater-fingerprint.gradle +135 -0
- package/android/src/main/cpp/HotUpdaterRecovery.cpp +291 -21
- package/android/src/main/java/com/hotupdater/ActivityStartGate.kt +176 -15
- package/android/src/main/java/com/hotupdater/ArtifactFileResolver.kt +20 -8
- package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +145 -31
- package/android/src/main/java/com/hotupdater/CohortService.kt +10 -2
- package/android/src/main/java/com/hotupdater/FileManagerService.kt +3 -1
- package/android/src/main/java/com/hotupdater/HotUpdaterConfig.kt +249 -21
- package/android/src/main/java/com/hotupdater/HotUpdaterException.kt +8 -4
- package/android/src/main/java/com/hotupdater/HotUpdaterHeldContent.kt +92 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +319 -113
- package/android/src/main/java/com/hotupdater/HotUpdaterInstance.kt +87 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterInstanceEnvironment.kt +323 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterMainThread.kt +46 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterProcess.kt +30 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryAttribution.kt +492 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryManager.kt +1541 -159
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoverySlots.kt +137 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryState.kt +4 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterRuntimeInstance.kt +53 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterUpdateCheck.kt +149 -0
- package/android/src/main/java/com/hotupdater/InstallIdentityService.kt +12 -2
- package/android/src/main/java/com/hotupdater/NativeConfigUtils.kt +5 -6
- package/android/src/main/java/com/hotupdater/NativeUpdateCheck.kt +172 -0
- package/android/src/main/java/com/hotupdater/NativeUpdateChecker.kt +1007 -0
- package/android/src/main/java/com/hotupdater/NativeUpdateEventQueue.kt +111 -0
- package/android/src/main/java/com/hotupdater/OkHttpUpdateCheckTransport.kt +88 -0
- package/android/src/main/java/com/hotupdater/ReleaseCatalog.kt +491 -0
- package/android/src/main/java/com/hotupdater/ReleaseCatalogClient.kt +405 -0
- package/android/src/main/java/com/hotupdater/ReleaseSelection.kt +474 -0
- package/android/src/main/java/com/hotupdater/SignatureVerifier.kt +32 -10
- package/android/src/main/java/com/hotupdater/StrictJson.kt +392 -0
- package/android/src/main/java/com/hotupdater/VersionedPreferencesService.kt +24 -9
- package/android/src/main/java/com/hotupdater/WeakIdentitySet.kt +76 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/BitReader.java +314 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/BrotliError.java +47 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/BrotliInputStream.java +174 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/BrotliRuntimeException.java +21 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/Context.java +58 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/Decode.java +1574 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/Decoder.java +72 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/Dictionary.java +103 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/DictionaryData.java +82 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/Huffman.java +143 -0
- package/{LICENSE → android/src/main/java/com/hotupdater/vendor/brotli/dec/LICENSE} +6 -20
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/README.md +39 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/State.java +100 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/Transform.java +240 -0
- package/android/src/main/java/com/hotupdater/vendor/brotli/dec/Utils.java +163 -0
- package/android/src/main/resources/META-INF/LICENSE-brotli +19 -0
- package/android/src/newarch/HotUpdater.kt +53 -15
- package/android/src/newarch/HotUpdaterModule.kt +42 -17
- package/android/src/newarch/JavaScriptExceptionHooks.kt +45 -8
- package/android/src/oldarch/HotUpdater.kt +51 -12
- package/android/src/oldarch/HotUpdaterModule.kt +43 -17
- package/android/src/oldarch/HotUpdaterSpec.kt +2 -0
- package/android/src/oldarch/JavaScriptExceptionHooks.kt +25 -16
- package/ios/HotUpdater/Interface/HotUpdaterInterface.h +13 -0
- package/ios/HotUpdater/Internal/ArtifactFileResolver.swift +38 -7
- package/ios/HotUpdater/Internal/BuiltInAssetResolver.swift +10 -4
- package/ios/HotUpdater/Internal/BundleFileStorageService.swift +186 -48
- package/ios/HotUpdater/Internal/CohortService.swift +8 -0
- package/ios/HotUpdater/Internal/HotUpdater.mm +821 -71
- package/ios/HotUpdater/Internal/HotUpdaterAsync.swift +7 -0
- package/ios/HotUpdater/Internal/HotUpdaterConfig.swift +208 -25
- package/ios/HotUpdater/Internal/HotUpdaterFingerprintHash.m +10 -0
- package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +940 -261
- package/ios/HotUpdater/Internal/HotUpdaterInstanceEnvironment.swift +492 -0
- package/ios/HotUpdater/Internal/HotUpdaterInstanceRouter.swift +83 -0
- package/ios/HotUpdater/Internal/HotUpdaterInterface.swift +28 -1
- package/ios/HotUpdater/Internal/HotUpdaterLaunchRecovery.swift +1553 -0
- package/ios/HotUpdater/Internal/HotUpdaterNativeUpdates.swift +353 -0
- package/ios/HotUpdater/Internal/LaunchPreparationLock.swift +54 -0
- package/ios/HotUpdater/Internal/NativeUpdateCheck.swift +2051 -0
- package/ios/HotUpdater/Internal/ReleaseCatalog.swift +634 -0
- package/ios/HotUpdater/Internal/ReleaseCatalogCacheService.swift +1 -1
- package/ios/HotUpdater/Internal/ReleaseSelection.swift +482 -0
- package/ios/HotUpdater/Internal/SignatureVerifier.swift +27 -10
- package/ios/HotUpdater/Internal/StrictJson.swift +363 -0
- package/ios/HotUpdater/Internal/URLSessionDownloadService.swift +4 -2
- package/ios/HotUpdater/Internal/UpdateFailure.swift +2 -0
- package/ios/HotUpdater/Package.swift +11 -0
- package/ios/HotUpdater/Public/HotUpdater/HotUpdater.h +4 -0
- package/ios/HotUpdater/Public/HotUpdater.h +21 -2
- package/ios/HotUpdater/Recovery/HotUpdaterRecoveryHooks.mm +66 -0
- package/ios/Plugins/HotUpdaterFingerprintPlugin/HotUpdaterFingerprintPlugin.swift +45 -0
- package/ios/scripts/generate-fingerprint-hash.zsh +85 -0
- package/lib/commonjs/checkForUpdate.js +3 -1
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/index.js +9 -12
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/native.js +24 -79
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/nativeUpdateEvents.js +66 -0
- package/lib/commonjs/nativeUpdateEvents.js.map +1 -0
- package/lib/commonjs/sdkVersion.js +1 -1
- package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
- package/lib/module/checkForUpdate.js +3 -1
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/index.js +10 -13
- package/lib/module/index.js.map +1 -1
- package/lib/module/native.js +19 -73
- package/lib/module/native.js.map +1 -1
- package/lib/module/nativeUpdateEvents.js +61 -0
- package/lib/module/nativeUpdateEvents.js.map +1 -0
- package/lib/module/sdkVersion.js +1 -1
- package/lib/module/specs/NativeHotUpdater.js.map +1 -1
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +4 -14
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/native.d.ts +9 -46
- package/lib/typescript/commonjs/native.d.ts.map +1 -1
- package/lib/typescript/commonjs/nativeUpdateEvents.d.ts +12 -0
- package/lib/typescript/commonjs/nativeUpdateEvents.d.ts.map +1 -0
- package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +19 -3
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +4 -14
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/native.d.ts +9 -46
- package/lib/typescript/module/native.d.ts.map +1 -1
- package/lib/typescript/module/nativeUpdateEvents.d.ts +12 -0
- package/lib/typescript/module/nativeUpdateEvents.d.ts.map +1 -0
- package/lib/typescript/module/sdkVersion.d.ts +1 -1
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts +19 -3
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/checkForUpdate.ts +7 -1
- package/src/index.ts +9 -17
- package/src/native.ts +19 -91
- package/src/nativeUpdateEvents.ts +77 -0
- package/src/sdkVersion.ts +1 -1
- package/src/specs/NativeHotUpdater.ts +20 -3
- package/android/libs/README.md +0 -50
- package/android/libs/hot-updater-brotli-dec-1.2.0.jar +0 -0
- package/android/src/bridge/BridgeReactInstance.kt +0 -38
- package/android/src/bridgeless/BridgeReactInstance.kt +0 -24
- package/android/src/main/java/com/hotupdater/ReactIntegrationManagerBase.kt +0 -34
- package/android/src/newarch/ReactIntegrationManager.kt +0 -185
- package/android/src/oldarch/ReactIntegrationManager.kt +0 -120
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/* Copyright 2015 Google Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
Distributed under MIT license.
|
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
package com.hotupdater.vendor.brotli.dec;
|
|
8
|
+
|
|
9
|
+
import static com.hotupdater.vendor.brotli.dec.BrotliError.BROTLI_ERROR;
|
|
10
|
+
import static com.hotupdater.vendor.brotli.dec.BrotliError.BROTLI_ERROR_CORRUPTED_PADDING_BITS;
|
|
11
|
+
import static com.hotupdater.vendor.brotli.dec.BrotliError.BROTLI_ERROR_READ_AFTER_END;
|
|
12
|
+
import static com.hotupdater.vendor.brotli.dec.BrotliError.BROTLI_ERROR_TRUNCATED_INPUT;
|
|
13
|
+
import static com.hotupdater.vendor.brotli.dec.BrotliError.BROTLI_ERROR_UNUSED_BYTES_AFTER_END;
|
|
14
|
+
import static com.hotupdater.vendor.brotli.dec.BrotliError.BROTLI_OK;
|
|
15
|
+
import static com.hotupdater.vendor.brotli.dec.BrotliError.BROTLI_PANIC_UNALIGNED_COPY_BYTES;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Bit reading helpers.
|
|
19
|
+
*/
|
|
20
|
+
final class BitReader {
|
|
21
|
+
|
|
22
|
+
// Possible values: {5, 6}. 5 corresponds to 32-bit build, 6 to 64-bit. This value is used for
|
|
23
|
+
// JIT conditional compilation.
|
|
24
|
+
private static final int LOG_BITNESS = Utils.getLogBintness();
|
|
25
|
+
|
|
26
|
+
// Not only Java compiler prunes "if (const false)" code, but JVM as well.
|
|
27
|
+
// Code under "if (BIT_READER_DEBUG != 0)" have zero performance impact (outside unit tests).
|
|
28
|
+
private static final int BIT_READER_DEBUG = Utils.isDebugMode();
|
|
29
|
+
|
|
30
|
+
static final int BITNESS = 1 << LOG_BITNESS;
|
|
31
|
+
|
|
32
|
+
private static final int BYTENESS = BITNESS / 8;
|
|
33
|
+
private static final int CAPACITY = 4096;
|
|
34
|
+
// After encountering the end of the input stream, this amount of zero bytes will be appended.
|
|
35
|
+
private static final int SLACK = 64;
|
|
36
|
+
private static final int BUFFER_SIZE = CAPACITY + SLACK;
|
|
37
|
+
// Don't bother to replenish the buffer while this number of bytes is available.
|
|
38
|
+
private static final int SAFEGUARD = 36;
|
|
39
|
+
private static final int WATERLINE = CAPACITY - SAFEGUARD;
|
|
40
|
+
|
|
41
|
+
// "Half" refers to "half of native integer type", i.e. on 64-bit machines it is 32-bit type,
|
|
42
|
+
// on 32-bit machines it is 16-bit.
|
|
43
|
+
private static final int HALF_BITNESS = BITNESS / 2;
|
|
44
|
+
private static final int HALF_SIZE = BYTENESS / 2;
|
|
45
|
+
private static final int HALVES_CAPACITY = CAPACITY / HALF_SIZE;
|
|
46
|
+
private static final int HALF_BUFFER_SIZE = BUFFER_SIZE / HALF_SIZE;
|
|
47
|
+
|
|
48
|
+
private static final int LOG_HALF_SIZE = LOG_BITNESS - 4;
|
|
49
|
+
|
|
50
|
+
static final int HALF_WATERLINE = WATERLINE / HALF_SIZE;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Fills up the input buffer.
|
|
54
|
+
*
|
|
55
|
+
* <p> Should not be called if there are at least 36 bytes present after current position.
|
|
56
|
+
*
|
|
57
|
+
* <p> After encountering the end of the input stream, 64 additional zero bytes are copied to the
|
|
58
|
+
* buffer.
|
|
59
|
+
*/
|
|
60
|
+
static int readMoreInput(State s) {
|
|
61
|
+
if (s.endOfStreamReached != 0) {
|
|
62
|
+
if (halfAvailable(s) >= -2) {
|
|
63
|
+
return BROTLI_OK;
|
|
64
|
+
}
|
|
65
|
+
return Utils.makeError(s, BROTLI_ERROR_TRUNCATED_INPUT);
|
|
66
|
+
}
|
|
67
|
+
final int readOffset = s.halfOffset << LOG_HALF_SIZE;
|
|
68
|
+
int bytesInBuffer = CAPACITY - readOffset;
|
|
69
|
+
// Move unused bytes to the head of the buffer.
|
|
70
|
+
Utils.copyBytesWithin(s.byteBuffer, 0, readOffset, CAPACITY);
|
|
71
|
+
s.halfOffset = 0;
|
|
72
|
+
while (bytesInBuffer < CAPACITY) {
|
|
73
|
+
final int spaceLeft = CAPACITY - bytesInBuffer;
|
|
74
|
+
final int len = Utils.readInput(s, s.byteBuffer, bytesInBuffer, spaceLeft);
|
|
75
|
+
if (len < BROTLI_ERROR) {
|
|
76
|
+
return len;
|
|
77
|
+
}
|
|
78
|
+
// EOF is -1 in Java, but 0 in C#.
|
|
79
|
+
if (len <= 0) {
|
|
80
|
+
s.endOfStreamReached = 1;
|
|
81
|
+
s.tailBytes = bytesInBuffer;
|
|
82
|
+
bytesInBuffer += HALF_SIZE - 1;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
bytesInBuffer += len;
|
|
86
|
+
}
|
|
87
|
+
bytesToNibbles(s, bytesInBuffer);
|
|
88
|
+
return BROTLI_OK;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static int checkHealth(State s, int endOfStream) {
|
|
92
|
+
if (s.endOfStreamReached == 0) {
|
|
93
|
+
return BROTLI_OK;
|
|
94
|
+
}
|
|
95
|
+
final int byteOffset = (s.halfOffset << LOG_HALF_SIZE) + ((s.bitOffset + 7) >> 3) - BYTENESS;
|
|
96
|
+
if (byteOffset > s.tailBytes) {
|
|
97
|
+
return Utils.makeError(s, BROTLI_ERROR_READ_AFTER_END);
|
|
98
|
+
}
|
|
99
|
+
if ((endOfStream != 0) && (byteOffset != s.tailBytes)) {
|
|
100
|
+
return Utils.makeError(s, BROTLI_ERROR_UNUSED_BYTES_AFTER_END);
|
|
101
|
+
}
|
|
102
|
+
return BROTLI_OK;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static void assertAccumulatorHealthy(State s) {
|
|
106
|
+
if (s.bitOffset > BITNESS) {
|
|
107
|
+
throw new IllegalStateException("Accumulator underloaded: " + s.bitOffset);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static void fillBitWindow(State s) {
|
|
112
|
+
if (BIT_READER_DEBUG != 0) {
|
|
113
|
+
assertAccumulatorHealthy(s);
|
|
114
|
+
}
|
|
115
|
+
if (s.bitOffset >= HALF_BITNESS) {
|
|
116
|
+
// Same as doFillBitWindow. JVM fails to inline it.
|
|
117
|
+
if (BITNESS == 64) {
|
|
118
|
+
s.accumulator64 = ((long) s.intBuffer[s.halfOffset++] << HALF_BITNESS)
|
|
119
|
+
| Utils.shr64(s.accumulator64, HALF_BITNESS);
|
|
120
|
+
} else {
|
|
121
|
+
s.accumulator32 = ((int) s.shortBuffer[s.halfOffset++] << HALF_BITNESS)
|
|
122
|
+
| Utils.shr32(s.accumulator32, HALF_BITNESS);
|
|
123
|
+
}
|
|
124
|
+
s.bitOffset -= HALF_BITNESS;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static void doFillBitWindow(State s) {
|
|
129
|
+
if (BIT_READER_DEBUG != 0) {
|
|
130
|
+
assertAccumulatorHealthy(s);
|
|
131
|
+
}
|
|
132
|
+
if (BITNESS == 64) {
|
|
133
|
+
s.accumulator64 = ((long) s.intBuffer[s.halfOffset++] << HALF_BITNESS)
|
|
134
|
+
| Utils.shr64(s.accumulator64, HALF_BITNESS);
|
|
135
|
+
} else {
|
|
136
|
+
s.accumulator32 = ((int) s.shortBuffer[s.halfOffset++] << HALF_BITNESS)
|
|
137
|
+
| Utils.shr32(s.accumulator32, HALF_BITNESS);
|
|
138
|
+
}
|
|
139
|
+
s.bitOffset -= HALF_BITNESS;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static int peekBits(State s) {
|
|
143
|
+
if (BITNESS == 64) {
|
|
144
|
+
return (int) Utils.shr64(s.accumulator64, s.bitOffset);
|
|
145
|
+
} else {
|
|
146
|
+
return Utils.shr32(s.accumulator32, s.bitOffset);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Fetches bits from accumulator.
|
|
152
|
+
*
|
|
153
|
+
* WARNING: accumulator MUST contain at least the specified amount of bits,
|
|
154
|
+
* otherwise BitReader will become broken.
|
|
155
|
+
*/
|
|
156
|
+
static int readFewBits(State s, int n) {
|
|
157
|
+
final int v = peekBits(s) & ((1 << n) - 1);
|
|
158
|
+
s.bitOffset += n;
|
|
159
|
+
return v;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static int readBits(State s, int n) {
|
|
163
|
+
if (HALF_BITNESS >= 24) {
|
|
164
|
+
return readFewBits(s, n);
|
|
165
|
+
} else {
|
|
166
|
+
return (n <= 16) ? readFewBits(s, n) : readManyBits(s, n);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private static int readManyBits(State s, int n) {
|
|
171
|
+
final int low = readFewBits(s, 16);
|
|
172
|
+
doFillBitWindow(s);
|
|
173
|
+
return low | (readFewBits(s, n - 16) << 16);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
static int initBitReader(State s) {
|
|
177
|
+
s.byteBuffer = new byte[BUFFER_SIZE];
|
|
178
|
+
if (BITNESS == 64) {
|
|
179
|
+
s.accumulator64 = 0;
|
|
180
|
+
s.intBuffer = new int[HALF_BUFFER_SIZE];
|
|
181
|
+
} else {
|
|
182
|
+
s.accumulator32 = 0;
|
|
183
|
+
s.shortBuffer = new short[HALF_BUFFER_SIZE];
|
|
184
|
+
}
|
|
185
|
+
s.bitOffset = BITNESS;
|
|
186
|
+
s.halfOffset = HALVES_CAPACITY;
|
|
187
|
+
s.endOfStreamReached = 0;
|
|
188
|
+
return prepare(s);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private static int prepare(State s) {
|
|
192
|
+
if (s.halfOffset > BitReader.HALF_WATERLINE) {
|
|
193
|
+
final int result = readMoreInput(s);
|
|
194
|
+
if (result != BROTLI_OK) {
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
int health = checkHealth(s, 0);
|
|
199
|
+
if (health != BROTLI_OK) {
|
|
200
|
+
return health;
|
|
201
|
+
}
|
|
202
|
+
doFillBitWindow(s);
|
|
203
|
+
doFillBitWindow(s);
|
|
204
|
+
return BROTLI_OK;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static int reload(State s) {
|
|
208
|
+
if (s.bitOffset == BITNESS) {
|
|
209
|
+
return prepare(s);
|
|
210
|
+
}
|
|
211
|
+
return BROTLI_OK;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
static int jumpToByteBoundary(State s) {
|
|
215
|
+
final int padding = (BITNESS - s.bitOffset) & 7;
|
|
216
|
+
if (padding != 0) {
|
|
217
|
+
final int paddingBits = readFewBits(s, padding);
|
|
218
|
+
if (paddingBits != 0) {
|
|
219
|
+
return Utils.makeError(s, BROTLI_ERROR_CORRUPTED_PADDING_BITS);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return BROTLI_OK;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static int halfAvailable(State s) {
|
|
226
|
+
int limit = HALVES_CAPACITY;
|
|
227
|
+
if (s.endOfStreamReached != 0) {
|
|
228
|
+
limit = (s.tailBytes + (HALF_SIZE - 1)) >> LOG_HALF_SIZE;
|
|
229
|
+
}
|
|
230
|
+
return limit - s.halfOffset;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static int copyRawBytes(State s, byte[] data, int offset, int length) {
|
|
234
|
+
int pos = offset;
|
|
235
|
+
int len = length;
|
|
236
|
+
if ((s.bitOffset & 7) != 0) {
|
|
237
|
+
return Utils.makeError(s, BROTLI_PANIC_UNALIGNED_COPY_BYTES);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Drain accumulator.
|
|
241
|
+
while ((s.bitOffset != BITNESS) && (len != 0)) {
|
|
242
|
+
data[pos++] = (byte) peekBits(s);
|
|
243
|
+
s.bitOffset += 8;
|
|
244
|
+
len--;
|
|
245
|
+
}
|
|
246
|
+
if (len == 0) {
|
|
247
|
+
return BROTLI_OK;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Get data from shadow buffer with "sizeof(int)" granularity.
|
|
251
|
+
final int copyNibbles = Utils.min(halfAvailable(s), len >> LOG_HALF_SIZE);
|
|
252
|
+
if (copyNibbles > 0) {
|
|
253
|
+
final int readOffset = s.halfOffset << LOG_HALF_SIZE;
|
|
254
|
+
final int delta = copyNibbles << LOG_HALF_SIZE;
|
|
255
|
+
Utils.copyBytes(data, pos, s.byteBuffer, readOffset, readOffset + delta);
|
|
256
|
+
pos += delta;
|
|
257
|
+
len -= delta;
|
|
258
|
+
s.halfOffset += copyNibbles;
|
|
259
|
+
}
|
|
260
|
+
if (len == 0) {
|
|
261
|
+
return BROTLI_OK;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Read tail bytes.
|
|
265
|
+
if (halfAvailable(s) > 0) {
|
|
266
|
+
// length = 1..3
|
|
267
|
+
fillBitWindow(s);
|
|
268
|
+
while (len != 0) {
|
|
269
|
+
data[pos++] = (byte) peekBits(s);
|
|
270
|
+
s.bitOffset += 8;
|
|
271
|
+
len--;
|
|
272
|
+
}
|
|
273
|
+
return checkHealth(s, 0);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Now it is possible to copy bytes directly.
|
|
277
|
+
while (len > 0) {
|
|
278
|
+
final int chunkLen = Utils.readInput(s, data, pos, len);
|
|
279
|
+
if (chunkLen < BROTLI_ERROR) {
|
|
280
|
+
return chunkLen;
|
|
281
|
+
}
|
|
282
|
+
// EOF is -1 in Java, but 0 in C#.
|
|
283
|
+
if (chunkLen <= 0) {
|
|
284
|
+
return Utils.makeError(s, BROTLI_ERROR_TRUNCATED_INPUT);
|
|
285
|
+
}
|
|
286
|
+
pos += chunkLen;
|
|
287
|
+
len -= chunkLen;
|
|
288
|
+
}
|
|
289
|
+
return BROTLI_OK;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Translates bytes to halves (int/short).
|
|
294
|
+
*/
|
|
295
|
+
static void bytesToNibbles(State s, int byteLen) {
|
|
296
|
+
final byte[] byteBuffer = s.byteBuffer;
|
|
297
|
+
final int halfLen = byteLen >> LOG_HALF_SIZE;
|
|
298
|
+
if (BITNESS == 64) {
|
|
299
|
+
final int[] intBuffer = s.intBuffer;
|
|
300
|
+
for (int i = 0; i < halfLen; ++i) {
|
|
301
|
+
intBuffer[i] = ((int) byteBuffer[i * 4] & 0xFF)
|
|
302
|
+
| (((int) byteBuffer[(i * 4) + 1] & 0xFF) << 8)
|
|
303
|
+
| (((int) byteBuffer[(i * 4) + 2] & 0xFF) << 16)
|
|
304
|
+
| (((int) byteBuffer[(i * 4) + 3] & 0xFF) << 24);
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
final short[] shortBuffer = s.shortBuffer;
|
|
308
|
+
for (int i = 0; i < halfLen; ++i) {
|
|
309
|
+
shortBuffer[i] = (short) (((int) byteBuffer[i * 2] & 0xFF)
|
|
310
|
+
| (((int) byteBuffer[(i * 2) + 1] & 0xFF) << 8));
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* Copyright 2025 Google Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
Distributed under MIT license.
|
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
package com.hotupdater.vendor.brotli.dec;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Possible errors from decoder.
|
|
11
|
+
*/
|
|
12
|
+
public class BrotliError {
|
|
13
|
+
public static final int BROTLI_OK = 0;
|
|
14
|
+
public static final int BROTLI_OK_DONE = BROTLI_OK + 1;
|
|
15
|
+
public static final int BROTLI_OK_NEED_MORE_OUTPUT = BROTLI_OK + 2;
|
|
16
|
+
|
|
17
|
+
// It is important that actual error codes are LESS than -1!
|
|
18
|
+
public static final int BROTLI_ERROR = -1;
|
|
19
|
+
public static final int BROTLI_ERROR_CORRUPTED_CODE_LENGTH_TABLE = BROTLI_ERROR - 1;
|
|
20
|
+
public static final int BROTLI_ERROR_CORRUPTED_CONTEXT_MAP = BROTLI_ERROR - 2;
|
|
21
|
+
public static final int BROTLI_ERROR_CORRUPTED_HUFFMAN_CODE_HISTOGRAM = BROTLI_ERROR - 3;
|
|
22
|
+
public static final int BROTLI_ERROR_CORRUPTED_PADDING_BITS = BROTLI_ERROR - 4;
|
|
23
|
+
public static final int BROTLI_ERROR_CORRUPTED_RESERVED_BIT = BROTLI_ERROR - 5;
|
|
24
|
+
public static final int BROTLI_ERROR_DUPLICATE_SIMPLE_HUFFMAN_SYMBOL = BROTLI_ERROR - 6;
|
|
25
|
+
public static final int BROTLI_ERROR_EXUBERANT_NIBBLE = BROTLI_ERROR - 7;
|
|
26
|
+
public static final int BROTLI_ERROR_INVALID_BACKWARD_REFERENCE = BROTLI_ERROR - 8;
|
|
27
|
+
public static final int BROTLI_ERROR_INVALID_METABLOCK_LENGTH = BROTLI_ERROR - 9;
|
|
28
|
+
public static final int BROTLI_ERROR_INVALID_WINDOW_BITS = BROTLI_ERROR - 10;
|
|
29
|
+
public static final int BROTLI_ERROR_NEGATIVE_DISTANCE = BROTLI_ERROR - 11;
|
|
30
|
+
public static final int BROTLI_ERROR_READ_AFTER_END = BROTLI_ERROR - 12;
|
|
31
|
+
public static final int BROTLI_ERROR_READ_FAILED = BROTLI_ERROR - 13;
|
|
32
|
+
public static final int BROTLI_ERROR_SYMBOL_OUT_OF_RANGE = BROTLI_ERROR - 14;
|
|
33
|
+
public static final int BROTLI_ERROR_TRUNCATED_INPUT = BROTLI_ERROR - 15;
|
|
34
|
+
public static final int BROTLI_ERROR_UNUSED_BYTES_AFTER_END = BROTLI_ERROR - 16;
|
|
35
|
+
public static final int BROTLI_ERROR_UNUSED_HUFFMAN_SPACE = BROTLI_ERROR - 17;
|
|
36
|
+
|
|
37
|
+
public static final int BROTLI_PANIC = -21;
|
|
38
|
+
public static final int BROTLI_PANIC_ALREADY_CLOSED = BROTLI_PANIC - 1;
|
|
39
|
+
public static final int BROTLI_PANIC_MAX_DISTANCE_TOO_SMALL = BROTLI_PANIC - 2;
|
|
40
|
+
public static final int BROTLI_PANIC_STATE_NOT_FRESH = BROTLI_PANIC - 3;
|
|
41
|
+
public static final int BROTLI_PANIC_STATE_NOT_INITIALIZED = BROTLI_PANIC - 4;
|
|
42
|
+
public static final int BROTLI_PANIC_STATE_NOT_UNINITIALIZED = BROTLI_PANIC - 5;
|
|
43
|
+
public static final int BROTLI_PANIC_TOO_MANY_DICTIONARY_CHUNKS = BROTLI_PANIC - 6;
|
|
44
|
+
public static final int BROTLI_PANIC_UNEXPECTED_STATE = BROTLI_PANIC - 7;
|
|
45
|
+
public static final int BROTLI_PANIC_UNREACHABLE = BROTLI_PANIC - 8;
|
|
46
|
+
public static final int BROTLI_PANIC_UNALIGNED_COPY_BYTES = BROTLI_PANIC - 9;
|
|
47
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/* Copyright 2015 Google Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
Distributed under MIT license.
|
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
package com.hotupdater.vendor.brotli.dec;
|
|
8
|
+
|
|
9
|
+
import java.io.IOException;
|
|
10
|
+
import java.io.InputStream;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* {@link InputStream} decorator that decompresses brotli data.
|
|
14
|
+
*
|
|
15
|
+
* <p> Not thread-safe.
|
|
16
|
+
*/
|
|
17
|
+
public class BrotliInputStream extends InputStream {
|
|
18
|
+
|
|
19
|
+
public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 256;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Value expected by InputStream contract when stream is over.
|
|
23
|
+
*
|
|
24
|
+
* In Java it is -1.
|
|
25
|
+
* In C# it is 0 (should be patched during transpilation).
|
|
26
|
+
*/
|
|
27
|
+
private static final int END_OF_STREAM_MARKER = -1;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Internal buffer used for efficient byte-by-byte reading.
|
|
31
|
+
*/
|
|
32
|
+
private byte[] buffer;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Number of decoded but still unused bytes in internal buffer.
|
|
36
|
+
*/
|
|
37
|
+
private int remainingBufferBytes;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Next unused byte offset.
|
|
41
|
+
*/
|
|
42
|
+
private int bufferOffset;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Decoder state.
|
|
46
|
+
*/
|
|
47
|
+
private final State state = new State();
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Creates a {@link InputStream} wrapper that decompresses brotli data.
|
|
51
|
+
*
|
|
52
|
+
* <p> For byte-by-byte reading ({@link #read()}) internal buffer with
|
|
53
|
+
* {@link #DEFAULT_INTERNAL_BUFFER_SIZE} size is allocated and used.
|
|
54
|
+
*
|
|
55
|
+
* <p> Will block the thread until first {@link BitReader#CAPACITY} bytes of data of source
|
|
56
|
+
* are available.
|
|
57
|
+
*
|
|
58
|
+
* @param source underlying data source
|
|
59
|
+
* @throws IOException in case of corrupted data or source stream problems
|
|
60
|
+
*/
|
|
61
|
+
public BrotliInputStream(InputStream source) throws IOException {
|
|
62
|
+
this(source, DEFAULT_INTERNAL_BUFFER_SIZE);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates a {@link InputStream} wrapper that decompresses brotli data.
|
|
67
|
+
*
|
|
68
|
+
* <p> For byte-by-byte reading ({@link #read()}) internal buffer of specified size is
|
|
69
|
+
* allocated and used.
|
|
70
|
+
*
|
|
71
|
+
* <p> Will block the thread until first {@link BitReader#CAPACITY} bytes of data of source
|
|
72
|
+
* are available.
|
|
73
|
+
*
|
|
74
|
+
* @param source compressed data source
|
|
75
|
+
* @param byteReadBufferSize size of internal buffer used in case of
|
|
76
|
+
* byte-by-byte reading
|
|
77
|
+
* @throws IOException in case of corrupted data or source stream problems
|
|
78
|
+
*/
|
|
79
|
+
public BrotliInputStream(InputStream source, int byteReadBufferSize) throws IOException {
|
|
80
|
+
if (byteReadBufferSize <= 0) {
|
|
81
|
+
throw new IllegalArgumentException("Bad buffer size:" + byteReadBufferSize);
|
|
82
|
+
} else if (source == null) {
|
|
83
|
+
throw new IllegalArgumentException("source is null");
|
|
84
|
+
}
|
|
85
|
+
this.buffer = new byte[byteReadBufferSize];
|
|
86
|
+
this.remainingBufferBytes = 0;
|
|
87
|
+
this.bufferOffset = 0;
|
|
88
|
+
try {
|
|
89
|
+
state.input = source;
|
|
90
|
+
Decode.initState(state);
|
|
91
|
+
} catch (BrotliRuntimeException ex) {
|
|
92
|
+
throw new IOException("Brotli decoder initialization failed", ex);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public void attachDictionaryChunk(byte[] data) {
|
|
97
|
+
Decode.attachDictionaryChunk(state, data);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public void enableEagerOutput() {
|
|
101
|
+
Decode.enableEagerOutput(state);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public void enableLargeWindow() {
|
|
105
|
+
Decode.enableLargeWindow(state);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* {@inheritDoc}
|
|
110
|
+
*/
|
|
111
|
+
@Override
|
|
112
|
+
public void close() throws IOException {
|
|
113
|
+
Decode.close(state);
|
|
114
|
+
Utils.closeInput(state);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* {@inheritDoc}
|
|
119
|
+
*/
|
|
120
|
+
@Override
|
|
121
|
+
public int read() throws IOException {
|
|
122
|
+
if (bufferOffset >= remainingBufferBytes) {
|
|
123
|
+
remainingBufferBytes = read(buffer, 0, buffer.length);
|
|
124
|
+
bufferOffset = 0;
|
|
125
|
+
if (remainingBufferBytes == END_OF_STREAM_MARKER) {
|
|
126
|
+
// Both Java and C# return the same value for EOF on single-byte read.
|
|
127
|
+
return -1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return buffer[bufferOffset++] & 0xFF;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* {@inheritDoc}
|
|
135
|
+
*/
|
|
136
|
+
@Override
|
|
137
|
+
public int read(byte[] destBuffer, int destOffset, int destLen) throws IOException {
|
|
138
|
+
if (destOffset < 0) {
|
|
139
|
+
throw new IllegalArgumentException("Bad offset: " + destOffset);
|
|
140
|
+
} else if (destLen < 0) {
|
|
141
|
+
throw new IllegalArgumentException("Bad length: " + destLen);
|
|
142
|
+
} else if (destOffset + destLen > destBuffer.length) {
|
|
143
|
+
throw new IllegalArgumentException(
|
|
144
|
+
"Buffer overflow: " + (destOffset + destLen) + " > " + destBuffer.length);
|
|
145
|
+
} else if (destLen == 0) {
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
int copyLen = Math.max(remainingBufferBytes - bufferOffset, 0);
|
|
149
|
+
if (copyLen != 0) {
|
|
150
|
+
copyLen = Math.min(copyLen, destLen);
|
|
151
|
+
System.arraycopy(buffer, bufferOffset, destBuffer, destOffset, copyLen);
|
|
152
|
+
bufferOffset += copyLen;
|
|
153
|
+
destOffset += copyLen;
|
|
154
|
+
destLen -= copyLen;
|
|
155
|
+
if (destLen == 0) {
|
|
156
|
+
return copyLen;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
state.output = destBuffer;
|
|
161
|
+
state.outputOffset = destOffset;
|
|
162
|
+
state.outputLength = destLen;
|
|
163
|
+
state.outputUsed = 0;
|
|
164
|
+
Decode.decompress(state);
|
|
165
|
+
copyLen += state.outputUsed;
|
|
166
|
+
copyLen = (copyLen > 0) ? copyLen : END_OF_STREAM_MARKER;
|
|
167
|
+
return copyLen;
|
|
168
|
+
} catch (BrotliRuntimeException ex) {
|
|
169
|
+
throw new IOException("Brotli stream decoding failed", ex);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// <{[INJECTED CODE]}>
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* Copyright 2015 Google Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
Distributed under MIT license.
|
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
package com.hotupdater.vendor.brotli.dec;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Unchecked exception used internally.
|
|
11
|
+
*/
|
|
12
|
+
class BrotliRuntimeException extends RuntimeException {
|
|
13
|
+
|
|
14
|
+
BrotliRuntimeException(String message) {
|
|
15
|
+
super(message);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
BrotliRuntimeException(String message, Throwable cause) {
|
|
19
|
+
super(message, cause);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* Copyright 2015 Google Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
Distributed under MIT license.
|
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
package com.hotupdater.vendor.brotli.dec;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Common context lookup table for all context modes.
|
|
11
|
+
*/
|
|
12
|
+
final class Context {
|
|
13
|
+
|
|
14
|
+
static final int[] LOOKUP = new int[2048];
|
|
15
|
+
|
|
16
|
+
private static final String UTF_MAP = " !! ! \"#$##%#$&'##(#)#+++++++++"
|
|
17
|
+
+ "+((&*'##,---,---,-----,-----,-----&#'###.///.///./////./////./////&#'# ";
|
|
18
|
+
private static final String UTF_RLE = "A/* ': & : $ \u0081 @";
|
|
19
|
+
|
|
20
|
+
private static void unpackLookupTable(int[] lookup, String utfMap, String utfRle) {
|
|
21
|
+
// LSB6, MSB6, SIGNED
|
|
22
|
+
for (int i = 0; i < 256; ++i) {
|
|
23
|
+
lookup[i] = i & 0x3F;
|
|
24
|
+
lookup[512 + i] = i >> 2;
|
|
25
|
+
lookup[1792 + i] = 2 + (i >> 6);
|
|
26
|
+
}
|
|
27
|
+
// UTF8
|
|
28
|
+
for (int i = 0; i < 128; ++i) {
|
|
29
|
+
lookup[1024 + i] = 4 * ((int) utfMap.charAt(i) - 32);
|
|
30
|
+
}
|
|
31
|
+
for (int i = 0; i < 64; ++i) {
|
|
32
|
+
lookup[1152 + i] = i & 1;
|
|
33
|
+
lookup[1216 + i] = 2 + (i & 1);
|
|
34
|
+
}
|
|
35
|
+
int offset = 1280;
|
|
36
|
+
for (int k = 0; k < 19; ++k) {
|
|
37
|
+
final int value = k & 3;
|
|
38
|
+
final int rep = (int) utfRle.charAt(k) - 32;
|
|
39
|
+
for (int i = 0; i < rep; ++i) {
|
|
40
|
+
lookup[offset++] = value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// SIGNED
|
|
44
|
+
for (int i = 0; i < 16; ++i) {
|
|
45
|
+
lookup[1792 + i] = 1;
|
|
46
|
+
lookup[2032 + i] = 6;
|
|
47
|
+
}
|
|
48
|
+
lookup[1792] = 0;
|
|
49
|
+
lookup[2047] = 7;
|
|
50
|
+
for (int i = 0; i < 256; ++i) {
|
|
51
|
+
lookup[1536 + i] = lookup[1792 + i] << 3;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static {
|
|
56
|
+
unpackLookupTable(LOOKUP, UTF_MAP, UTF_RLE);
|
|
57
|
+
}
|
|
58
|
+
}
|