cbor-extract 2.2.2 → 2.2.3
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/package.json +8 -8
- package/src/extract.cpp +42 -19
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cbor-extract",
|
|
3
3
|
"author": "Kris Zyp",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.3",
|
|
5
5
|
"description": "Node addon for string extraction for cbor-x",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"prebuild-libc": "prebuildify-platform-packages --tag-libc --target 24.14.0 && ENABLE_V8_FUNCTIONS=false prebuildify-platform-packages --platform-packages --napi --tag-libc --target 20.20.0",
|
|
19
19
|
"prebuild-libc-alpine": "ENABLE_V8_FUNCTIONS=false prebuildify-cross --image alpine --tag-libc --napi --target 20.20.0",
|
|
20
20
|
"publish-all": "cd prebuilds/darwin-x64 && npm publish --access public && cd ../darwin-arm64 && npm publish --access public && cd ../linux-x64 && npm publish --access public && cd ../linux-arm64 && npm publish --access public && cd ../linux-arm && npm publish --access public && cd ../.. && npm publish --access public",
|
|
21
|
-
"test": "node ./index.js"
|
|
21
|
+
"test": "node ./index.js && node test/scan.cjs && node test/strings.cjs"
|
|
22
22
|
},
|
|
23
23
|
"main": "./index.js",
|
|
24
24
|
"gypfile": true,
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"prebuildify-cross": "5.0.0"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|
|
43
|
-
"@cbor-extract/cbor-extract-darwin-arm64": "2.2.
|
|
44
|
-
"@cbor-extract/cbor-extract-darwin-x64": "2.2.
|
|
45
|
-
"@cbor-extract/cbor-extract-linux-arm": "2.2.
|
|
46
|
-
"@cbor-extract/cbor-extract-linux-arm64": "2.2.
|
|
47
|
-
"@cbor-extract/cbor-extract-linux-x64": "2.2.
|
|
48
|
-
"@cbor-extract/cbor-extract-win32-x64": "2.2.
|
|
43
|
+
"@cbor-extract/cbor-extract-darwin-arm64": "2.2.3",
|
|
44
|
+
"@cbor-extract/cbor-extract-darwin-x64": "2.2.3",
|
|
45
|
+
"@cbor-extract/cbor-extract-linux-arm": "2.2.3",
|
|
46
|
+
"@cbor-extract/cbor-extract-linux-arm64": "2.2.3",
|
|
47
|
+
"@cbor-extract/cbor-extract-linux-x64": "2.2.3",
|
|
48
|
+
"@cbor-extract/cbor-extract-win32-x64": "2.2.3"
|
|
49
49
|
}
|
|
50
50
|
}
|
package/src/extract.cpp
CHANGED
|
@@ -39,7 +39,24 @@ public:
|
|
|
39
39
|
uint32_t stringStart = 0;
|
|
40
40
|
uint32_t lastStringEnd = 0;
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
// false with a RangeError pending when V8 rejects the string (longer than its maximum length)
|
|
43
|
+
bool createString(napi_env env, uint32_t start, uint32_t length, bool latin1, napi_value* value) {
|
|
44
|
+
napi_status status = latin1 ?
|
|
45
|
+
napi_create_string_latin1(env, (const char*) source + start, length, value) :
|
|
46
|
+
napi_create_string_utf8(env, (const char*) source + start, length, value);
|
|
47
|
+
if (status != napi_ok) {
|
|
48
|
+
napi_throw_range_error(env, NULL, "Unable to create a string from the buffer");
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
bool appendString(napi_env env, uint32_t start, uint32_t length, bool latin1) {
|
|
54
|
+
if (!createString(env, start, length, latin1, &target[writePosition]))
|
|
55
|
+
return false;
|
|
56
|
+
writePosition++;
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
bool readString(napi_env env, uint32_t length, bool allowStringBlocks) {
|
|
43
60
|
uint32_t start = position;
|
|
44
61
|
uint32_t end = position + length;
|
|
45
62
|
if (allowStringBlocks) { // for larger strings, we don't bother to check every character for being latin, and just go right to creating a new string
|
|
@@ -54,30 +71,28 @@ public:
|
|
|
54
71
|
if (position < end) {
|
|
55
72
|
// non-latin character
|
|
56
73
|
if (lastStringEnd) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
target[writePosition++] = value;
|
|
74
|
+
if (!appendString(env, stringStart, lastStringEnd - stringStart, true))
|
|
75
|
+
return false;
|
|
60
76
|
lastStringEnd = 0;
|
|
61
77
|
}
|
|
62
78
|
// use standard utf-8 conversion
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
target[writePosition++] = value;
|
|
79
|
+
if (!appendString(env, start, length, false))
|
|
80
|
+
return false;
|
|
66
81
|
position = end;
|
|
67
|
-
return;
|
|
82
|
+
return true;
|
|
68
83
|
}
|
|
69
84
|
|
|
70
85
|
if (lastStringEnd) {
|
|
71
86
|
if (start - lastStringEnd > 40 || end - stringStart > 6000) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
target[writePosition++] = value;
|
|
87
|
+
if (!appendString(env, stringStart, lastStringEnd - stringStart, true))
|
|
88
|
+
return false;
|
|
75
89
|
stringStart = start;
|
|
76
90
|
}
|
|
77
91
|
} else {
|
|
78
92
|
stringStart = start;
|
|
79
93
|
}
|
|
80
94
|
lastStringEnd = end;
|
|
95
|
+
return true;
|
|
81
96
|
}
|
|
82
97
|
napi_value extractStrings(napi_env env, uint32_t startingPosition, uint32_t size, uint32_t firstStringSize, uint8_t* inputSource) {
|
|
83
98
|
writePosition = 0;
|
|
@@ -87,7 +102,8 @@ public:
|
|
|
87
102
|
if ((uint64_t)startingPosition + firstStringSize > size) {
|
|
88
103
|
return unexpectedEnd(env);
|
|
89
104
|
}
|
|
90
|
-
readString(env, firstStringSize, firstStringSize < 0x100)
|
|
105
|
+
if (!readString(env, firstStringSize, firstStringSize < 0x100))
|
|
106
|
+
return NULL;
|
|
91
107
|
while (position < size) {
|
|
92
108
|
uint8_t token = source[position++];
|
|
93
109
|
uint8_t majorType = token >> 5;
|
|
@@ -96,23 +112,23 @@ public:
|
|
|
96
112
|
uint32_t length;
|
|
97
113
|
switch (token) {
|
|
98
114
|
case 0x18:
|
|
99
|
-
if (position
|
|
115
|
+
if (size - position < 1) {
|
|
100
116
|
return unexpectedEnd(env);
|
|
101
117
|
}
|
|
102
118
|
length = source[position++];
|
|
103
119
|
break;
|
|
104
120
|
case 0x19:
|
|
105
|
-
if (position
|
|
121
|
+
if (size - position < 2) {
|
|
106
122
|
return unexpectedEnd(env);
|
|
107
123
|
}
|
|
108
124
|
length = source[position++] << 8;
|
|
109
125
|
length += source[position++];
|
|
110
126
|
break;
|
|
111
127
|
case 0x1a:
|
|
112
|
-
if (position
|
|
128
|
+
if (size - position < 4) {
|
|
113
129
|
return unexpectedEnd(env);
|
|
114
130
|
}
|
|
115
|
-
length = source[position++] << 24;
|
|
131
|
+
length = (uint32_t) source[position++] << 24;
|
|
116
132
|
length += source[position++] << 16;
|
|
117
133
|
length += source[position++] << 8;
|
|
118
134
|
length += source[position++];
|
|
@@ -124,13 +140,16 @@ public:
|
|
|
124
140
|
}
|
|
125
141
|
if (majorType == 3) {
|
|
126
142
|
// string
|
|
127
|
-
if (
|
|
143
|
+
if (length > size - position) {
|
|
128
144
|
return unexpectedEnd(env);
|
|
129
145
|
}
|
|
130
|
-
readString(env, length, length < 0x100)
|
|
146
|
+
if (!readString(env, length, length < 0x100))
|
|
147
|
+
return NULL;
|
|
131
148
|
if (writePosition >= MAX_TARGET_SIZE - 1) // reserve slot for double-write
|
|
132
149
|
break;
|
|
133
150
|
} else { // binary data
|
|
151
|
+
if (length >= size - position) // a declared length that reaches the end ends the scan, and can't wrap position
|
|
152
|
+
break;
|
|
134
153
|
position += length;
|
|
135
154
|
}
|
|
136
155
|
|
|
@@ -153,7 +172,8 @@ public:
|
|
|
153
172
|
}
|
|
154
173
|
if (lastStringEnd) {
|
|
155
174
|
napi_value value;
|
|
156
|
-
|
|
175
|
+
if (!createString(env, stringStart, lastStringEnd - stringStart, true, &value))
|
|
176
|
+
return NULL;
|
|
157
177
|
if (writePosition == 0) {
|
|
158
178
|
return value;
|
|
159
179
|
}
|
|
@@ -197,6 +217,9 @@ napi_value extractStrings(napi_env env, napi_callback_info info) {
|
|
|
197
217
|
if (size > buffer_size || position > buffer_size) {
|
|
198
218
|
return unexpectedEnd(env);
|
|
199
219
|
}
|
|
220
|
+
// fixed-size skips advance by at most 8 past a position below size, so this keeps them from wrapping
|
|
221
|
+
if (size > UINT32_MAX - 8)
|
|
222
|
+
size = UINT32_MAX - 8;
|
|
200
223
|
return extractor->extractStrings(env, position, size, firstStringSize, source);
|
|
201
224
|
}
|
|
202
225
|
#define EXPORT_NAPI_FUNCTION(name, func) { napi_property_descriptor desc = { name, 0, func, 0, 0, 0, (napi_property_attributes) (napi_writable | napi_configurable), 0 }; napi_define_properties(env, exports, 1, &desc); }
|