react-native-mmkv 3.0.0-beta.7 → 3.0.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/MMKV/Core/KeyValueHolder.cpp +1 -1
- package/MMKV/Core/KeyValueHolder.h +5 -1
- package/MMKV/Core/MMKVPredef.h +1 -1
- package/MMKV/Core/MMKV_IO.cpp +18 -12
- package/MMKV/Core/MMKV_OSX.cpp +12 -26
- package/MMKV/Core/ThreadLock.cpp +1 -3
- package/MMKV/Core/aes/AESCrypt.cpp +26 -6
- package/MMKV/Core/aes/AESCrypt.h +5 -1
- package/package.json +1 -1
|
@@ -131,7 +131,7 @@ uint32_t KeyValueHolderCrypt::realValueSize() const {
|
|
|
131
131
|
|
|
132
132
|
// get decrypt data with [position, -1)
|
|
133
133
|
static MMBuffer decryptBuffer(AESCrypt &crypter, const MMBuffer &inputBuffer, size_t position) {
|
|
134
|
-
|
|
134
|
+
size_t smallBuffer[16 / sizeof(size_t)];
|
|
135
135
|
auto basePtr = (uint8_t *) inputBuffer.getPtr();
|
|
136
136
|
auto ptr = basePtr;
|
|
137
137
|
for (size_t index = sizeof(smallBuffer); index < position; index += sizeof(smallBuffer)) {
|
|
@@ -78,7 +78,11 @@ struct KeyValueHolderCrypt {
|
|
|
78
78
|
return sizeof(KeyValueHolderCrypt) - offsetof(KeyValueHolderCrypt, paddedValue);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
static
|
|
81
|
+
static constexpr size_t MediumBufferSize() {
|
|
82
|
+
return 256;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static bool isValueStoredAsOffset(size_t valueSize) { return valueSize > MediumBufferSize(); }
|
|
82
86
|
|
|
83
87
|
KeyValueHolderCrypt() = default;
|
|
84
88
|
KeyValueHolderCrypt(const void *valuePtr, size_t valueLength);
|
package/MMKV/Core/MMKVPredef.h
CHANGED
package/MMKV/Core/MMKV_IO.cpp
CHANGED
|
@@ -338,7 +338,6 @@ void MMKV::checkLoadData() {
|
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
constexpr uint32_t ItemSizeHolder = 0x00ffffff;
|
|
342
341
|
constexpr uint32_t ItemSizeHolderSize = 4;
|
|
343
342
|
|
|
344
343
|
static pair<MMBuffer, size_t> prepareEncode(const MMKVMap &dic) {
|
|
@@ -911,17 +910,22 @@ KVHolderRet_t MMKV::doOverrideDataWithKey(const MMBuffer &data,
|
|
|
911
910
|
} else {
|
|
912
911
|
m_crypter->resetIV();
|
|
913
912
|
}
|
|
914
|
-
if (KeyValueHolderCrypt::isValueStoredAsOffset(valueLength)) {
|
|
915
|
-
m_crypter->getCurStatus(t_status);
|
|
916
|
-
}
|
|
917
913
|
}
|
|
918
914
|
#endif
|
|
919
915
|
try {
|
|
920
916
|
// write ItemSizeHolder
|
|
921
917
|
m_output->setPosition(0);
|
|
922
|
-
m_output->
|
|
918
|
+
m_output->writeUInt32(AESCrypt::randomItemSizeHolder(ItemSizeHolderSize));
|
|
923
919
|
m_actualSize = ItemSizeHolderSize;
|
|
924
|
-
|
|
920
|
+
#ifndef MMKV_DISABLE_CRYPT
|
|
921
|
+
if (m_crypter) {
|
|
922
|
+
auto ptr = (uint8_t *) m_file->getMemory() + Fixed32Size;
|
|
923
|
+
m_crypter->encrypt(ptr, ptr, m_actualSize);
|
|
924
|
+
if (KeyValueHolderCrypt::isValueStoredAsOffset(valueLength)) {
|
|
925
|
+
m_crypter->getCurStatus(t_status);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
#endif
|
|
925
929
|
if (isKeyEncoded) {
|
|
926
930
|
m_output->writeRawData(keyData);
|
|
927
931
|
} else {
|
|
@@ -941,10 +945,10 @@ KVHolderRet_t MMKV::doOverrideDataWithKey(const MMBuffer &data,
|
|
|
941
945
|
|
|
942
946
|
auto offset = static_cast<uint32_t>(m_actualSize);
|
|
943
947
|
m_actualSize += size;
|
|
944
|
-
auto ptr = (uint8_t *) m_file->getMemory() + Fixed32Size;
|
|
945
948
|
#ifndef MMKV_DISABLE_CRYPT
|
|
946
949
|
if (m_crypter) {
|
|
947
|
-
|
|
950
|
+
auto ptr = (uint8_t *) m_file->getMemory() + Fixed32Size + offset;
|
|
951
|
+
m_crypter->encrypt(ptr, ptr, size);
|
|
948
952
|
}
|
|
949
953
|
#endif
|
|
950
954
|
recalculateCRCDigestOnly();
|
|
@@ -1128,7 +1132,7 @@ memmoveDictionary(MMKVMap &dic, CodedOutputData *output, uint8_t *ptr, AESCrypt
|
|
|
1128
1132
|
}
|
|
1129
1133
|
}
|
|
1130
1134
|
// hold the fake size of dictionary's serialization result
|
|
1131
|
-
output->
|
|
1135
|
+
output->writeUInt32(AESCrypt::randomItemSizeHolder(ItemSizeHolderSize));
|
|
1132
1136
|
auto writtenSize = static_cast<size_t>(writePtr - originOutputPtr);
|
|
1133
1137
|
#ifndef MMKV_DISABLE_CRYPT
|
|
1134
1138
|
if (encrypter) {
|
|
@@ -1159,14 +1163,16 @@ static void memmoveDictionary(MMKVMapCrypt &dic,
|
|
|
1159
1163
|
}
|
|
1160
1164
|
sort(vec.begin(), vec.end(), [](auto left, auto right) { return left->offset < right->offset; });
|
|
1161
1165
|
}
|
|
1162
|
-
auto
|
|
1166
|
+
auto sizeHolderSize = ItemSizeHolderSize;
|
|
1167
|
+
auto sizeHolder = AESCrypt::randomItemSizeHolder(sizeHolderSize);
|
|
1163
1168
|
if (!vec.empty()) {
|
|
1164
1169
|
auto smallestOffset = vec.front()->offset;
|
|
1165
1170
|
if (smallestOffset != ItemSizeHolderSize && smallestOffset <= 5) {
|
|
1166
1171
|
sizeHolderSize = smallestOffset;
|
|
1167
1172
|
assert(sizeHolderSize != 0);
|
|
1168
1173
|
static const uint32_t ItemSizeHolders[] = {0, 0x0f, 0xff, 0xffff, 0xffffff, 0xffffffff};
|
|
1169
|
-
sizeHolder =
|
|
1174
|
+
sizeHolder = AESCrypt::randomItemSizeHolder(sizeHolderSize);
|
|
1175
|
+
assert(sizeHolder >= ItemSizeHolders[sizeHolderSize] && sizeHolder <= ItemSizeHolders[sizeHolderSize]);
|
|
1170
1176
|
}
|
|
1171
1177
|
}
|
|
1172
1178
|
output->writeRawVarint32(static_cast<int32_t>(sizeHolder));
|
|
@@ -1230,7 +1236,7 @@ static void memmoveDictionary(MMKVMapCrypt &dic,
|
|
|
1230
1236
|
|
|
1231
1237
|
static void fullWriteBackWholeData(MMBuffer allData, size_t totalSize, CodedOutputData *output) {
|
|
1232
1238
|
auto originOutputPtr = output->curWritePointer();
|
|
1233
|
-
output->
|
|
1239
|
+
output->writeUInt32(AESCrypt::randomItemSizeHolder(ItemSizeHolderSize));
|
|
1234
1240
|
if (allData.length() > 0) {
|
|
1235
1241
|
auto dataSize = CodedInputData(allData.getPtr(), allData.length()).readUInt32();
|
|
1236
1242
|
if (dataSize > 0) {
|
package/MMKV/Core/MMKV_OSX.cpp
CHANGED
|
@@ -260,35 +260,21 @@ MMKV::appendDataWithKey(const MMBuffer &data, MMKVKey_t key, const KeyValueHolde
|
|
|
260
260
|
|
|
261
261
|
pair<bool, KeyValueHolder>
|
|
262
262
|
MMKV::overrideDataWithKey(const MMBuffer &data, MMKVKey_t key, const KeyValueHolderCrypt &kvHolder, bool isDataHolder) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// only one key in dict, do not append, just rewrite from beginning
|
|
266
|
-
m_actualSize = 0;
|
|
267
|
-
m_output->setPosition(0);
|
|
268
|
-
|
|
269
|
-
auto m_tmpDic = m_dic;
|
|
270
|
-
auto m_tmpDicCrypt = m_dicCrypt;
|
|
271
|
-
if (m_crypter) {
|
|
272
|
-
m_dicCrypt = new MMKVMapCrypt();
|
|
273
|
-
} else {
|
|
274
|
-
m_dic = new MMKVMap();
|
|
263
|
+
if (kvHolder.type != KeyValueHolderType_Offset) {
|
|
264
|
+
return overrideDataWithKey(data, key, isDataHolder);
|
|
275
265
|
}
|
|
266
|
+
SCOPED_LOCK(m_exclusiveProcessLock);
|
|
276
267
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
m_actualSize = old_actualSize;
|
|
281
|
-
m_output->setPosition(old_position);
|
|
282
|
-
}
|
|
268
|
+
uint32_t keyLength = kvHolder.keySize;
|
|
269
|
+
// size needed to encode the key
|
|
270
|
+
size_t rawKeySize = keyLength + pbRawVarint32Size(keyLength);
|
|
283
271
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
return ret;
|
|
272
|
+
auto basePtr = (uint8_t *) m_file->getMemory() + Fixed32Size;
|
|
273
|
+
MMBuffer keyData(rawKeySize);
|
|
274
|
+
AESCrypt decrypter = m_crypter->cloneWithStatus(kvHolder.cryptStatus);
|
|
275
|
+
decrypter.decrypt(basePtr + kvHolder.offset, keyData.getPtr(), rawKeySize);
|
|
276
|
+
|
|
277
|
+
return doOverrideDataWithKey(data, keyData, isDataHolder, keyLength);
|
|
292
278
|
}
|
|
293
279
|
# endif
|
|
294
280
|
|
package/MMKV/Core/ThreadLock.cpp
CHANGED
|
@@ -38,10 +38,8 @@ ThreadLock::ThreadLock() : m_lock({}) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
ThreadLock::~ThreadLock() {
|
|
41
|
-
#ifdef MMKV_OHOS
|
|
42
|
-
// OHOS's pthread is buggy, check for POC: https://gist.github.com/lingol/622af352e090e0490ebacfe3a38b9221
|
|
43
41
|
pthread_mutex_unlock(&m_lock);
|
|
44
|
-
|
|
42
|
+
|
|
45
43
|
pthread_mutex_destroy(&m_lock);
|
|
46
44
|
}
|
|
47
45
|
|
|
@@ -25,12 +25,25 @@
|
|
|
25
25
|
#include <cstring>
|
|
26
26
|
#include <ctime>
|
|
27
27
|
|
|
28
|
+
namespace mmkv {
|
|
29
|
+
|
|
30
|
+
// assuming size in [1, 5]
|
|
31
|
+
uint32_t AESCrypt::randomItemSizeHolder(uint32_t size) {
|
|
32
|
+
constexpr uint32_t ItemSizeHolders[] = {0, 0x80, 0x4000, 0x200000, 0x10000000, 0};
|
|
33
|
+
auto ItemSizeHolderMin = ItemSizeHolders[size - 1];
|
|
34
|
+
auto ItemSizeHolderMax = ItemSizeHolders[size] - 1;
|
|
35
|
+
|
|
36
|
+
srand((unsigned) time(nullptr));
|
|
37
|
+
auto result = static_cast<uint32_t>(rand());
|
|
38
|
+
result = result % (ItemSizeHolderMax - ItemSizeHolderMin + 1);
|
|
39
|
+
result += ItemSizeHolderMin;
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
#ifndef MMKV_DISABLE_CRYPT
|
|
29
44
|
|
|
30
45
|
using namespace openssl;
|
|
31
46
|
|
|
32
|
-
namespace mmkv {
|
|
33
|
-
|
|
34
47
|
AESCrypt::AESCrypt(const void *key, size_t keyLength, const void *iv, size_t ivLength) {
|
|
35
48
|
if (key && keyLength > 0) {
|
|
36
49
|
memcpy(m_key, key, (keyLength > AES_KEY_LEN) ? AES_KEY_LEN : keyLength);
|
|
@@ -161,8 +174,6 @@ AESCrypt AESCrypt::cloneWithStatus(const AESCryptStatus &status) const {
|
|
|
161
174
|
return AESCrypt(*this, status);
|
|
162
175
|
}
|
|
163
176
|
|
|
164
|
-
} // namespace mmkv
|
|
165
|
-
|
|
166
177
|
# ifdef MMKV_DEBUG
|
|
167
178
|
|
|
168
179
|
# include "../MMKVLog.h"
|
|
@@ -170,8 +181,17 @@ AESCrypt AESCrypt::cloneWithStatus(const AESCryptStatus &status) const {
|
|
|
170
181
|
|
|
171
182
|
namespace mmkv {
|
|
172
183
|
|
|
184
|
+
void testRandomPlaceHolder() {
|
|
185
|
+
for (uint32_t size = 1; size < 6; size++) {
|
|
186
|
+
auto holder = AESCrypt::randomItemSizeHolder(size);
|
|
187
|
+
MMKVInfo("holder 0x%x for size %u", holder, size);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
173
191
|
// check if AESCrypt is encrypt-decrypt full-duplex
|
|
174
192
|
void AESCrypt::testAESCrypt() {
|
|
193
|
+
testRandomPlaceHolder();
|
|
194
|
+
|
|
175
195
|
const uint8_t plainText[] = "Hello, OpenSSL-mmkv::AESCrypt::testAESCrypt() with AES CFB 128.";
|
|
176
196
|
constexpr size_t textLength = sizeof(plainText) - 1;
|
|
177
197
|
|
|
@@ -250,7 +270,7 @@ void AESCrypt::testAESCrypt() {
|
|
|
250
270
|
delete[] decryptText;
|
|
251
271
|
}
|
|
252
272
|
|
|
253
|
-
} // namespace mmkv
|
|
254
|
-
|
|
255
273
|
# endif // MMKV_DEBUG
|
|
256
274
|
#endif // MMKV_DISABLE_CRYPT
|
|
275
|
+
|
|
276
|
+
} // namespace mmkv
|
package/MMKV/Core/aes/AESCrypt.h
CHANGED
|
@@ -29,7 +29,10 @@
|
|
|
29
29
|
#ifdef MMKV_DISABLE_CRYPT
|
|
30
30
|
|
|
31
31
|
namespace mmkv {
|
|
32
|
-
class AESCrypt
|
|
32
|
+
class AESCrypt {
|
|
33
|
+
public:
|
|
34
|
+
static uint32_t randomItemSizeHolder(uint32_t size);
|
|
35
|
+
};
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
#else
|
|
@@ -88,6 +91,7 @@ public:
|
|
|
88
91
|
void getKey(void *output) const;
|
|
89
92
|
|
|
90
93
|
static void fillRandomIV(void *vector);
|
|
94
|
+
static uint32_t randomItemSizeHolder(uint32_t size);
|
|
91
95
|
|
|
92
96
|
// just forbid it for possibly misuse
|
|
93
97
|
explicit AESCrypt(const AESCrypt &other) = delete;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mmkv",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "The fastest key/value storage for React Native. ~30x faster than AsyncStorage! Works on Android, iOS and Web.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|