@ohos-ports/bare-buffer 3.7.1-beta.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.
Files changed (155) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +26 -0
  3. package/binding.c +1077 -0
  4. package/binding.gyp +32 -0
  5. package/binding.js +1 -0
  6. package/build/Release/bare_buffer.node +0 -0
  7. package/deps/libbase64/.clang-format +10 -0
  8. package/deps/libbase64/.gitattributes +1 -0
  9. package/deps/libbase64/.github/workflows/integrate.yml +45 -0
  10. package/deps/libbase64/.github/workflows/nightly.yml +28 -0
  11. package/deps/libbase64/.prettierrc +1 -0
  12. package/deps/libbase64/CMakeLists.txt +71 -0
  13. package/deps/libbase64/LICENSE +201 -0
  14. package/deps/libbase64/NOTICE +13 -0
  15. package/deps/libbase64/README.md +11 -0
  16. package/deps/libbase64/include/base64.h +323 -0
  17. package/deps/libbase64/package.json +25 -0
  18. package/deps/libbase64/src/base64.c +22 -0
  19. package/deps/libbase64/test/CMakeLists.txt +31 -0
  20. package/deps/libbase64/test/decode-invalid.c +35 -0
  21. package/deps/libbase64/test/decode-length.c +23 -0
  22. package/deps/libbase64/test/decode.c +36 -0
  23. package/deps/libbase64/test/encode-length.c +22 -0
  24. package/deps/libbase64/test/encode.c +42 -0
  25. package/deps/libbase64/test/fuzz/CMakeLists.txt +18 -0
  26. package/deps/libbase64/test/fuzz/decode/utf16le.c +53 -0
  27. package/deps/libbase64/test/fuzz/decode/utf8.c +47 -0
  28. package/deps/libbase64/test/fuzz/encode/utf16le.c +56 -0
  29. package/deps/libbase64/test/fuzz/encode/utf8.c +56 -0
  30. package/deps/libhex/.clang-format +10 -0
  31. package/deps/libhex/.gitattributes +1 -0
  32. package/deps/libhex/.github/workflows/integrate.yml +45 -0
  33. package/deps/libhex/.github/workflows/nightly.yml +28 -0
  34. package/deps/libhex/.prettierrc +1 -0
  35. package/deps/libhex/CMakeLists.txt +72 -0
  36. package/deps/libhex/LICENSE +201 -0
  37. package/deps/libhex/NOTICE +13 -0
  38. package/deps/libhex/README.md +11 -0
  39. package/deps/libhex/include/hex.h +163 -0
  40. package/deps/libhex/package.json +25 -0
  41. package/deps/libhex/src/hex.c +16 -0
  42. package/deps/libhex/test/CMakeLists.txt +31 -0
  43. package/deps/libhex/test/decode-invalid.c +37 -0
  44. package/deps/libhex/test/decode-length.c +23 -0
  45. package/deps/libhex/test/decode.c +25 -0
  46. package/deps/libhex/test/encode-length.c +22 -0
  47. package/deps/libhex/test/encode.c +25 -0
  48. package/deps/libhex/test/fuzz/CMakeLists.txt +18 -0
  49. package/deps/libhex/test/fuzz/decode/utf16le.c +53 -0
  50. package/deps/libhex/test/fuzz/decode/utf8.c +47 -0
  51. package/deps/libhex/test/fuzz/encode/utf16le.c +36 -0
  52. package/deps/libhex/test/fuzz/encode/utf8.c +36 -0
  53. package/deps/libutf/.clang-format +10 -0
  54. package/deps/libutf/.gitattributes +1 -0
  55. package/deps/libutf/.github/workflows/integrate.yml +45 -0
  56. package/deps/libutf/.github/workflows/nightly.yml +28 -0
  57. package/deps/libutf/.prettierrc +1 -0
  58. package/deps/libutf/CMakeLists.txt +105 -0
  59. package/deps/libutf/LICENSE +201 -0
  60. package/deps/libutf/NOTICE +13 -0
  61. package/deps/libutf/README.md +11 -0
  62. package/deps/libutf/include/utf/string.h +1655 -0
  63. package/deps/libutf/include/utf.h +132 -0
  64. package/deps/libutf/package.json +24 -0
  65. package/deps/libutf/src/ascii/validate.c +47 -0
  66. package/deps/libutf/src/endianness.c +19 -0
  67. package/deps/libutf/src/endianness.h +54 -0
  68. package/deps/libutf/src/latin1/convert-to-utf16.c +37 -0
  69. package/deps/libutf/src/latin1/convert-to-utf32.c +34 -0
  70. package/deps/libutf/src/latin1/convert-to-utf8.c +58 -0
  71. package/deps/libutf/src/latin1/length-from-utf16.c +26 -0
  72. package/deps/libutf/src/latin1/length-from-utf32.c +26 -0
  73. package/deps/libutf/src/latin1/length-from-utf8.c +34 -0
  74. package/deps/libutf/src/utf16/convert-to-latin1.c +41 -0
  75. package/deps/libutf/src/utf16/convert-to-utf32.c +56 -0
  76. package/deps/libutf/src/utf16/convert-to-utf8.c +80 -0
  77. package/deps/libutf/src/utf16/length-from-latin1.c +26 -0
  78. package/deps/libutf/src/utf16/length-from-utf32.c +33 -0
  79. package/deps/libutf/src/utf16/length-from-utf8.c +38 -0
  80. package/deps/libutf/src/utf16/validate.c +53 -0
  81. package/deps/libutf/src/utf32/convert-to-latin1.c +40 -0
  82. package/deps/libutf/src/utf32/convert-to-utf16.c +56 -0
  83. package/deps/libutf/src/utf32/convert-to-utf8.c +71 -0
  84. package/deps/libutf/src/utf32/length-from-latin1.c +26 -0
  85. package/deps/libutf/src/utf32/length-from-utf16.c +35 -0
  86. package/deps/libutf/src/utf32/length-from-utf8.c +35 -0
  87. package/deps/libutf/src/utf32/string.c +149 -0
  88. package/deps/libutf/src/utf32/validate.c +39 -0
  89. package/deps/libutf/src/utf8/convert-to-latin1.c +70 -0
  90. package/deps/libutf/src/utf8/convert-to-utf16.c +95 -0
  91. package/deps/libutf/src/utf8/convert-to-utf32.c +110 -0
  92. package/deps/libutf/src/utf8/length-from-latin1.c +32 -0
  93. package/deps/libutf/src/utf8/length-from-utf16.c +48 -0
  94. package/deps/libutf/src/utf8/length-from-utf32.c +35 -0
  95. package/deps/libutf/src/utf8/string.c +149 -0
  96. package/deps/libutf/src/utf8/validate.c +107 -0
  97. package/deps/libutf/test/CMakeLists.txt +56 -0
  98. package/deps/libutf/test/fuzz/CMakeLists.txt +26 -0
  99. package/deps/libutf/test/fuzz/corpus/.gitignore +2 -0
  100. package/deps/libutf/test/fuzz/crashes/.gitignore +2 -0
  101. package/deps/libutf/test/fuzz/latin1/convert-to-utf16.c +32 -0
  102. package/deps/libutf/test/fuzz/latin1/convert-to-utf32.c +32 -0
  103. package/deps/libutf/test/fuzz/latin1/convert-to-utf8.c +33 -0
  104. package/deps/libutf/test/fuzz/utf16/convert-to-latin1.c +36 -0
  105. package/deps/libutf/test/fuzz/utf16/convert-to-utf32.c +38 -0
  106. package/deps/libutf/test/fuzz/utf16/convert-to-utf8.c +38 -0
  107. package/deps/libutf/test/fuzz/utf32/convert-to-latin1.c +36 -0
  108. package/deps/libutf/test/fuzz/utf32/convert-to-utf16.c +38 -0
  109. package/deps/libutf/test/fuzz/utf32/convert-to-utf8.c +38 -0
  110. package/deps/libutf/test/fuzz/utf8/convert-to-latin1.c +33 -0
  111. package/deps/libutf/test/fuzz/utf8/convert-to-utf16.c +35 -0
  112. package/deps/libutf/test/fuzz/utf8/convert-to-utf32.c +35 -0
  113. package/deps/libutf/test/utf16/utf8-convert.c +45 -0
  114. package/deps/libutf/test/utf16/utf8-length.c +41 -0
  115. package/deps/libutf/test/utf16/validate-invalid.c +50 -0
  116. package/deps/libutf/test/utf16/validate.c +32 -0
  117. package/deps/libutf/test/utf32/string-append.c +74 -0
  118. package/deps/libutf/test/utf32/string-compare.c +108 -0
  119. package/deps/libutf/test/utf32/string-erase.c +79 -0
  120. package/deps/libutf/test/utf32/string-index.c +102 -0
  121. package/deps/libutf/test/utf32/string-insert.c +92 -0
  122. package/deps/libutf/test/utf32/string-last-index.c +71 -0
  123. package/deps/libutf/test/utf32/string-prepend.c +51 -0
  124. package/deps/libutf/test/utf32/string-replace.c +88 -0
  125. package/deps/libutf/test/utf32/string-reserve.c +99 -0
  126. package/deps/libutf/test/utf32/string-substring.c +93 -0
  127. package/deps/libutf/test/utf8/latin1-convert.c +23 -0
  128. package/deps/libutf/test/utf8/string-append.c +23 -0
  129. package/deps/libutf/test/utf8/string-compare.c +67 -0
  130. package/deps/libutf/test/utf8/string-erase.c +75 -0
  131. package/deps/libutf/test/utf8/string-index.c +99 -0
  132. package/deps/libutf/test/utf8/string-last-index.c +68 -0
  133. package/deps/libutf/test/utf8/string-prepend.c +23 -0
  134. package/deps/libutf/test/utf8/string-replace.c +74 -0
  135. package/deps/libutf/test/utf8/string-reserve.c +51 -0
  136. package/deps/libutf/test/utf8/string-substring.c +68 -0
  137. package/deps/libutf/test/utf8/utf16-convert.c +32 -0
  138. package/deps/libutf/test/utf8/utf16-length.c +29 -0
  139. package/deps/libutf/test/utf8/validate-invalid.c +26 -0
  140. package/deps/libutf/test/utf8/validate.c +21 -0
  141. package/global.d.ts +21 -0
  142. package/global.js +6 -0
  143. package/index.d.ts +769 -0
  144. package/index.js +1339 -0
  145. package/lib/ascii.js +36 -0
  146. package/lib/base64.js +25 -0
  147. package/lib/base64url.js +25 -0
  148. package/lib/checked.js +23 -0
  149. package/lib/constants.d.ts +7 -0
  150. package/lib/constants.js +3 -0
  151. package/lib/hex.js +20 -0
  152. package/lib/latin1.js +14 -0
  153. package/lib/utf16le.js +20 -0
  154. package/lib/utf8.js +18 -0
  155. package/package.json +64 -0
@@ -0,0 +1,323 @@
1
+ #ifndef BASE64_H
2
+ #define BASE64_H
3
+
4
+ #include <stdbool.h>
5
+ #include <stddef.h>
6
+ #include <stdint.h>
7
+ #include <utf.h>
8
+
9
+ #ifdef __cplusplus
10
+ extern "C" {
11
+ #endif
12
+
13
+ static const char base64__alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
14
+
15
+ static const char base64url__alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
16
+
17
+ static const char base64__inverse_alphabet[256] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
18
+
19
+ static inline int
20
+ base64__encode_utf8(const uint8_t *buffer, size_t buffer_len, utf8_t *string, size_t *string_len, bool url_safe) {
21
+ const char *alphabet = url_safe ? base64url__alphabet : base64__alphabet;
22
+
23
+ bool pad = !url_safe;
24
+
25
+ size_t len = pad ? 4 * ((buffer_len + 2) / 3) : ((buffer_len * 4 + 2) / 3);
26
+
27
+ if (string == NULL) {
28
+ *string_len = len;
29
+ return 0;
30
+ }
31
+
32
+ if (*string_len < len) return -1;
33
+
34
+ bool terminate = *string_len > len;
35
+
36
+ *string_len = len;
37
+
38
+ size_t k = 0, i = 0, n = buffer_len;
39
+
40
+ uint8_t a, b, c;
41
+
42
+ for (; i + 2 < n; i += 3) {
43
+ a = buffer[i];
44
+ b = buffer[i + 1];
45
+ c = buffer[i + 2];
46
+
47
+ string[k++] = alphabet[a >> 2];
48
+ string[k++] = alphabet[((a & 0x03) << 4) | (b >> 4)];
49
+ string[k++] = alphabet[((b & 0x0f) << 2) | (c >> 6)];
50
+ string[k++] = alphabet[c & 0x3f];
51
+ }
52
+
53
+ if (i < n) {
54
+ a = buffer[i];
55
+
56
+ string[k++] = alphabet[a >> 2];
57
+
58
+ if (i + 1 < n) {
59
+ b = buffer[i + 1];
60
+
61
+ string[k++] = alphabet[((a & 0x03) << 4) | (b >> 4)];
62
+ string[k++] = alphabet[(b & 0x0f) << 2];
63
+
64
+ if (pad) string[k++] = '=';
65
+ } else {
66
+ string[k++] = alphabet[(a & 0x03) << 4];
67
+
68
+ if (pad) {
69
+ string[k++] = '=';
70
+ string[k++] = '=';
71
+ }
72
+ }
73
+ }
74
+
75
+ if (terminate) string[k] = '\0';
76
+
77
+ return 0;
78
+ }
79
+
80
+ static inline int
81
+ base64__encode_utf16le(const uint8_t *buffer, size_t buffer_len, utf16_t *string, size_t *string_len, bool url_safe) {
82
+ const char *alphabet = url_safe ? base64url__alphabet : base64__alphabet;
83
+
84
+ bool pad = !url_safe;
85
+
86
+ size_t len = pad ? 4 * ((buffer_len + 2) / 3) : ((buffer_len * 4 + 2) / 3);
87
+
88
+ if (string == NULL) {
89
+ *string_len = len;
90
+ return 0;
91
+ }
92
+
93
+ if (*string_len < len) return -1;
94
+
95
+ bool terminate = *string_len > len;
96
+
97
+ *string_len = len;
98
+
99
+ size_t k = 0, i = 0, n = buffer_len;
100
+
101
+ uint8_t a, b, c;
102
+
103
+ for (; i + 2 < n; i += 3) {
104
+ a = buffer[i];
105
+ b = buffer[i + 1];
106
+ c = buffer[i + 2];
107
+
108
+ string[k++] = alphabet[a >> 2];
109
+ string[k++] = alphabet[((a & 0x03) << 4) | (b >> 4)];
110
+ string[k++] = alphabet[((b & 0x0f) << 2) | (c >> 6)];
111
+ string[k++] = alphabet[c & 0x3f];
112
+ }
113
+
114
+ if (i < n) {
115
+ a = buffer[i];
116
+
117
+ string[k++] = alphabet[a >> 2];
118
+
119
+ if (i + 1 < n) {
120
+ b = buffer[i + 1];
121
+
122
+ string[k++] = alphabet[((a & 0x03) << 4) | (b >> 4)];
123
+ string[k++] = alphabet[(b & 0x0f) << 2];
124
+
125
+ if (pad) string[k++] = '=';
126
+ } else {
127
+ string[k++] = alphabet[(a & 0x03) << 4];
128
+
129
+ if (pad) {
130
+ string[k++] = '=';
131
+ string[k++] = '=';
132
+ }
133
+ }
134
+ }
135
+
136
+ if (terminate) string[k] = '\0';
137
+
138
+ return 0;
139
+ }
140
+
141
+ static inline int
142
+ base64__decode_utf8(const utf8_t *string, size_t string_len, uint8_t *buffer, size_t *buffer_len) {
143
+ if (string_len % 4 == 1) return -1;
144
+
145
+ if (string_len == 0) {
146
+ *buffer_len = 0;
147
+ return 0;
148
+ }
149
+
150
+ size_t pad = 0;
151
+ if (string_len >= 2 && string[string_len - 1] == '=') pad++;
152
+ if (string_len >= 2 && string[string_len - 2] == '=') pad++;
153
+
154
+ size_t trailing = string_len % 4;
155
+
156
+ size_t len = string_len / 4 * 3;
157
+
158
+ if (trailing == 2) len += 1;
159
+ else if (trailing == 3) len += 2;
160
+
161
+ len -= pad;
162
+
163
+ if (buffer == NULL) {
164
+ *buffer_len = len;
165
+ return 0;
166
+ }
167
+
168
+ if (*buffer_len < len) return -1;
169
+
170
+ *buffer_len = len;
171
+
172
+ size_t k = 0;
173
+ size_t i = 0;
174
+
175
+ for (; i + 3 < string_len; i += 4) {
176
+ char chunk[4];
177
+
178
+ for (size_t j = 0; j < 4; j++) {
179
+ chunk[j] = string[i + j] == '=' ? 0 : base64__inverse_alphabet[string[i + j]];
180
+
181
+ if (chunk[j] == (char) -1) return -1;
182
+ }
183
+
184
+ uint32_t triple = (chunk[0] << 18) + (chunk[1] << 12) + (chunk[2] << 6) + chunk[3];
185
+
186
+ if (k < len) buffer[k++] = (triple >> 2 * 8) & 0xff;
187
+ if (k < len) buffer[k++] = (triple >> 1 * 8) & 0xff;
188
+ if (k < len) buffer[k++] = (triple >> 0 * 8) & 0xff;
189
+ }
190
+
191
+ if (trailing) {
192
+ char chunk[4] = {0, 0, 0, 0};
193
+
194
+ for (size_t j = 0; j < trailing; j++) {
195
+ chunk[j] = base64__inverse_alphabet[string[i + j]];
196
+
197
+ if (chunk[j] == (char) -1) return -1;
198
+ }
199
+
200
+ uint32_t triple = (chunk[0] << 18) | (chunk[1] << 12) | (chunk[2] << 6) | chunk[3];
201
+
202
+ if (trailing == 2) {
203
+ buffer[k++] = (triple >> 16) & 0xff;
204
+ } else if (trailing == 3) {
205
+ buffer[k++] = (triple >> 16) & 0xff;
206
+ buffer[k++] = (triple >> 8) & 0xff;
207
+ }
208
+ }
209
+
210
+ return 0;
211
+ }
212
+
213
+ static inline int
214
+ base64__decode_utf16le(const utf16_t *string, size_t string_len, uint8_t *buffer, size_t *buffer_len) {
215
+ if (string_len % 4 == 1) return -1;
216
+
217
+ if (string_len == 0) {
218
+ *buffer_len = 0;
219
+ return 0;
220
+ }
221
+
222
+ size_t pad = 0;
223
+ if (string_len >= 2 && string[string_len - 1] == '=') pad++;
224
+ if (string_len >= 2 && string[string_len - 2] == '=') pad++;
225
+
226
+ size_t trailing = string_len % 4;
227
+
228
+ size_t len = string_len / 4 * 3;
229
+
230
+ if (trailing == 2) len += 1;
231
+ else if (trailing == 3) len += 2;
232
+
233
+ len -= pad;
234
+
235
+ if (buffer == NULL) {
236
+ *buffer_len = len;
237
+ return 0;
238
+ }
239
+
240
+ if (*buffer_len < len) return -1;
241
+
242
+ *buffer_len = len;
243
+
244
+ size_t k = 0;
245
+ size_t i = 0;
246
+
247
+ for (; i + 3 < string_len; i += 4) {
248
+ char chunk[4];
249
+
250
+ for (size_t j = 0; j < 4; j++) {
251
+ utf16_t c = string[i + j];
252
+ if (c >= 256) return -1;
253
+ chunk[j] = c == '=' ? 0 : base64__inverse_alphabet[c];
254
+
255
+ if (chunk[j] == (char) -1) return -1;
256
+ }
257
+
258
+ uint32_t triple = (chunk[0] << 18) + (chunk[1] << 12) + (chunk[2] << 6) + chunk[3];
259
+
260
+ if (k < len) buffer[k++] = (triple >> 2 * 8) & 0xff;
261
+ if (k < len) buffer[k++] = (triple >> 1 * 8) & 0xff;
262
+ if (k < len) buffer[k++] = (triple >> 0 * 8) & 0xff;
263
+ }
264
+
265
+ if (trailing) {
266
+ char chunk[4] = {0, 0, 0, 0};
267
+
268
+ for (size_t j = 0; j < trailing; j++) {
269
+ utf16_t c = string[i + j];
270
+ if (c >= 256) return -1;
271
+ chunk[j] = base64__inverse_alphabet[c];
272
+
273
+ if (chunk[j] == (char) -1) return -1;
274
+ }
275
+
276
+ uint32_t triple = (chunk[0] << 18) | (chunk[1] << 12) | (chunk[2] << 6) | chunk[3];
277
+
278
+ if (trailing == 2) {
279
+ buffer[k++] = (triple >> 16) & 0xff;
280
+ } else if (trailing == 3) {
281
+ buffer[k++] = (triple >> 16) & 0xff;
282
+ buffer[k++] = (triple >> 8) & 0xff;
283
+ }
284
+ }
285
+
286
+ return 0;
287
+ }
288
+
289
+ static inline int
290
+ base64_encode_utf8(const uint8_t *buffer, size_t buffer_len, utf8_t *string, size_t *string_len) {
291
+ return base64__encode_utf8(buffer, buffer_len, string, string_len, false /* url_safe */);
292
+ }
293
+
294
+ static inline int
295
+ base64url_encode_utf8(const uint8_t *buffer, size_t buffer_len, utf8_t *string, size_t *string_len) {
296
+ return base64__encode_utf8(buffer, buffer_len, string, string_len, true /* url_safe */);
297
+ }
298
+
299
+ static inline int
300
+ base64_decode_utf8(const utf8_t *string, size_t string_len, uint8_t *buffer, size_t *buffer_len) {
301
+ return base64__decode_utf8(string, string_len, buffer, buffer_len);
302
+ }
303
+
304
+ static inline int
305
+ base64_encode_utf16le(const uint8_t *buffer, size_t buffer_len, utf16_t *string, size_t *string_len) {
306
+ return base64__encode_utf16le(buffer, buffer_len, string, string_len, false /* url_safe */);
307
+ }
308
+
309
+ static inline int
310
+ base64url_encode_utf16le(const uint8_t *buffer, size_t buffer_len, utf16_t *string, size_t *string_len) {
311
+ return base64__encode_utf16le(buffer, buffer_len, string, string_len, true /* url_safe */);
312
+ }
313
+
314
+ static inline int
315
+ base64_decode_utf16le(const utf16_t *string, size_t string_len, uint8_t *buffer, size_t *buffer_len) {
316
+ return base64__decode_utf16le(string, string_len, buffer, buffer_len);
317
+ }
318
+
319
+ #ifdef __cplusplus
320
+ }
321
+ #endif
322
+
323
+ #endif // BASE64_H
@@ -0,0 +1,25 @@
1
+ {
2
+ "private": true,
3
+ "name": "libbase64",
4
+ "scripts": {
5
+ "format": "prettier --write .",
6
+ "lint": "prettier --check ."
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/holepunchto/libbase64.git"
11
+ },
12
+ "author": "Holepunch",
13
+ "license": "Apache-2.0",
14
+ "bugs": {
15
+ "url": "https://github.com/holepunchto/libbase64/issues"
16
+ },
17
+ "homepage": "https://github.com/holepunchto/libbase64#readme",
18
+ "devDependencies": {
19
+ "cmake-fetch": "^1.0.0",
20
+ "cmake-fuzz": "^0.1.0",
21
+ "lunte": "^1.8.0",
22
+ "prettier": "^3.8.3",
23
+ "prettier-config-holepunch": "^2.0.0"
24
+ }
25
+ }
@@ -0,0 +1,22 @@
1
+ #include <stdint.h>
2
+ #include <utf.h>
3
+
4
+ #include "../include/base64.h"
5
+
6
+ extern int
7
+ base64_encode_utf8(const uint8_t *buffer, size_t buffer_len, utf8_t *string, size_t *string_len);
8
+
9
+ extern int
10
+ base64url_encode_utf8(const uint8_t *buffer, size_t buffer_len, utf8_t *string, size_t *string_len);
11
+
12
+ extern int
13
+ base64_decode_utf8(const utf8_t *string, size_t string_len, uint8_t *buffer, size_t *buffer_len);
14
+
15
+ extern int
16
+ base64_encode_utf16le(const uint8_t *buffer, size_t buffer_len, utf16_t *string, size_t *string_len);
17
+
18
+ extern int
19
+ base64url_encode_utf16le(const uint8_t *buffer, size_t buffer_len, utf16_t *string, size_t *string_len);
20
+
21
+ extern int
22
+ base64_decode_utf16le(const utf16_t *string, size_t string_len, uint8_t *buffer, size_t *buffer_len);
@@ -0,0 +1,31 @@
1
+ list(APPEND tests
2
+ decode
3
+ decode-invalid
4
+ decode-length
5
+ encode
6
+ encode-length
7
+ )
8
+
9
+ foreach(test IN LISTS tests)
10
+ add_executable(${test} ${test}.c)
11
+
12
+ target_link_libraries(
13
+ ${test}
14
+ PRIVATE
15
+ base64_static
16
+ )
17
+
18
+ add_test(
19
+ NAME ${test}
20
+ COMMAND ${test}
21
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
22
+ )
23
+
24
+ set_tests_properties(
25
+ ${test}
26
+ PROPERTIES
27
+ TIMEOUT 30
28
+ )
29
+ endforeach()
30
+
31
+ add_subdirectory(fuzz)
@@ -0,0 +1,35 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+ #include <utf.h>
4
+
5
+ #include "../include/base64.h"
6
+
7
+ #define test_decode_invalid(string) \
8
+ { \
9
+ size_t string_len = strlen(string); \
10
+ size_t buffer_len = string_len; \
11
+ uint8_t buffer[buffer_len]; \
12
+ int err = base64_decode_utf8((utf8_t *) string, string_len, buffer, &buffer_len); \
13
+ assert(err != 0); \
14
+ };
15
+
16
+ #define test_decode_invalid_utf16le(...) \
17
+ { \
18
+ utf16_t string[] = __VA_ARGS__; \
19
+ size_t string_len = sizeof(string) / sizeof(utf16_t); \
20
+ size_t buffer_len = string_len; \
21
+ uint8_t buffer[buffer_len]; \
22
+ int err = base64_decode_utf16le(string, string_len, buffer, &buffer_len); \
23
+ assert(err != 0); \
24
+ };
25
+
26
+ int
27
+ main() {
28
+ test_decode_invalid("a");
29
+ test_decode_invalid("abc*");
30
+
31
+ test_decode_invalid_utf16le({0x0041, 0x0042, 0x0043, 0x0100});
32
+ test_decode_invalid_utf16le({0x0041, 0x0042, 0x0100});
33
+ test_decode_invalid_utf16le({0xffff, 0xffff, 0xffff, 0xffff});
34
+ test_decode_invalid_utf16le({0x0041, 0xd800, 0x0042, 0x0043});
35
+ }
@@ -0,0 +1,23 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+ #include <utf.h>
4
+
5
+ #include "../include/base64.h"
6
+
7
+ #define test_decode_length(string, expected) \
8
+ { \
9
+ size_t string_len = strlen(string); \
10
+ size_t buffer_len = 0; \
11
+ int err = base64_decode_utf8((utf8_t *) string, string_len, NULL, &buffer_len); \
12
+ assert(err == 0); \
13
+ assert(buffer_len == expected); \
14
+ };
15
+
16
+ int
17
+ main() {
18
+ test_decode_length("YQ==", 1);
19
+ test_decode_length("YWI=", 2);
20
+ test_decode_length("YWJj", 3);
21
+ test_decode_length("YWJjZA==", 4);
22
+ test_decode_length("YWJjZGU=", 5);
23
+ }
@@ -0,0 +1,36 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+ #include <utf.h>
4
+
5
+ #include "../include/base64.h"
6
+
7
+ #define test_decode(string, expected) \
8
+ { \
9
+ size_t string_len = strlen(string); \
10
+ size_t buffer_len = string_len; \
11
+ uint8_t buffer[buffer_len]; \
12
+ int err = base64_decode_utf8((utf8_t *) string, string_len, buffer, &buffer_len); \
13
+ assert(err == 0); \
14
+ assert(buffer_len == strlen(expected)); \
15
+ assert(strncmp((char *) buffer, expected, buffer_len) == 0); \
16
+ };
17
+
18
+ int
19
+ main() {
20
+ test_decode("YQ", "a");
21
+ test_decode("YQ==", "a");
22
+ test_decode("YWI", "ab");
23
+ test_decode("YWI=", "ab");
24
+ test_decode("YWJj", "abc");
25
+ test_decode("YWJjZA", "abcd");
26
+ test_decode("YWJjZA==", "abcd");
27
+ test_decode("YWJjZGU=", "abcde");
28
+
29
+ // URL unsafe
30
+ test_decode("+w", "\xfb");
31
+ test_decode("+w==", "\xfb");
32
+
33
+ // URL safe
34
+ test_decode("-w", "\xfb");
35
+ test_decode("-w==", "\xfb");
36
+ }
@@ -0,0 +1,22 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+
4
+ #include "../include/base64.h"
5
+
6
+ #define test_encode_length(buffer, expected) \
7
+ { \
8
+ size_t buffer_len = strlen(buffer); \
9
+ size_t string_len = 0; \
10
+ int err = base64_encode_utf8((uint8_t *) buffer, buffer_len, NULL, &string_len); \
11
+ assert(err == 0); \
12
+ assert(string_len == expected); \
13
+ };
14
+
15
+ int
16
+ main() {
17
+ test_encode_length("a", 4);
18
+ test_encode_length("ab", 4);
19
+ test_encode_length("abc", 4);
20
+ test_encode_length("abcd", 8);
21
+ test_encode_length("abcde", 8);
22
+ }
@@ -0,0 +1,42 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+ #include <utf.h>
4
+
5
+ #include "../include/base64.h"
6
+
7
+ #define test_encode(buffer, expected) \
8
+ { \
9
+ size_t buffer_len = strlen(buffer); \
10
+ size_t string_len = 4 * ((buffer_len + 2) / 3) + 1; \
11
+ char string[string_len]; \
12
+ int err = base64_encode_utf8((uint8_t *) buffer, buffer_len, (utf8_t *) string, &string_len); \
13
+ assert(err == 0); \
14
+ assert(string_len == strlen(expected)); \
15
+ assert(strncmp(string, expected, string_len) == 0); \
16
+ };
17
+
18
+ #define test_encode_url(buffer, expected) \
19
+ { \
20
+ size_t buffer_len = strlen(buffer); \
21
+ size_t string_len = ((buffer_len * 4 + 2) / 3) + 1; \
22
+ char string[string_len]; \
23
+ int err = base64url_encode_utf8((uint8_t *) buffer, buffer_len, (utf8_t *) string, &string_len); \
24
+ assert(err == 0); \
25
+ assert(string_len == strlen(expected)); \
26
+ assert(strncmp(string, expected, string_len) == 0); \
27
+ };
28
+
29
+ int
30
+ main() {
31
+ test_encode("a", "YQ==");
32
+ test_encode("ab", "YWI=");
33
+ test_encode("abc", "YWJj");
34
+ test_encode("abcd", "YWJjZA==");
35
+ test_encode("abcde", "YWJjZGU=");
36
+
37
+ // URL unsafe
38
+ test_encode("\xfb", "+w==");
39
+
40
+ // URL safe
41
+ test_encode_url("\xfb", "-w");
42
+ }
@@ -0,0 +1,18 @@
1
+ list(APPEND fuzzers
2
+ encode/utf8
3
+ encode/utf16le
4
+ decode/utf8
5
+ decode/utf16le
6
+ )
7
+
8
+ foreach(fuzzer IN LISTS fuzzers)
9
+ string(REPLACE "/" "_" name ${fuzzer})
10
+
11
+ add_fuzzer(fuzz_${name} ${fuzzer}.c)
12
+
13
+ target_link_libraries(
14
+ fuzz_${name}
15
+ PRIVATE
16
+ base64_static
17
+ )
18
+ endforeach()
@@ -0,0 +1,53 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+ #include <stdint.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+
7
+ #include "../../../include/base64.h"
8
+
9
+ int
10
+ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
11
+ // Reinterpret the raw bytes as a sequence of UTF-16 code units.
12
+ size_t units = size / sizeof(utf16_t);
13
+ utf16_t *string = units > 0 ? malloc(units * sizeof(utf16_t)) : NULL;
14
+
15
+ if (string != NULL) memcpy(string, data, units * sizeof(utf16_t));
16
+
17
+ size_t buffer_len = units;
18
+ uint8_t *buffer = buffer_len > 0 ? malloc(buffer_len) : NULL;
19
+
20
+ int err = base64_decode_utf16le(string, units, buffer, &buffer_len);
21
+
22
+ if (err == 0) {
23
+ // Re-encode the decoded bytes; the result must decode back identically.
24
+ size_t reencoded_len = 4 * ((buffer_len + 2) / 3);
25
+ utf16_t *reencoded = reencoded_len > 0 ? malloc(reencoded_len * sizeof(utf16_t)) : NULL;
26
+
27
+ size_t len = reencoded_len;
28
+ err = base64_encode_utf16le(buffer, buffer_len, reencoded, &len);
29
+
30
+ assert(err == 0);
31
+ assert(len == reencoded_len);
32
+
33
+ size_t roundtrip_len = buffer_len;
34
+ uint8_t *roundtrip = roundtrip_len > 0 ? malloc(roundtrip_len) : NULL;
35
+
36
+ err = base64_decode_utf16le(reencoded, reencoded_len, roundtrip, &roundtrip_len);
37
+
38
+ assert(err == 0);
39
+ assert(roundtrip_len == buffer_len);
40
+
41
+ if (buffer_len > 0) {
42
+ assert(memcmp(roundtrip, buffer, buffer_len) == 0);
43
+ }
44
+
45
+ free(roundtrip);
46
+ free(reencoded);
47
+ }
48
+
49
+ free(buffer);
50
+ free(string);
51
+
52
+ return 0;
53
+ }
@@ -0,0 +1,47 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+ #include <stdint.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+
7
+ #include "../../../include/base64.h"
8
+
9
+ int
10
+ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
11
+ // Decoded output is never larger than the input.
12
+ size_t buffer_len = size;
13
+ uint8_t *buffer = buffer_len > 0 ? malloc(buffer_len) : NULL;
14
+
15
+ int err = base64_decode_utf8((const utf8_t *) data, size, buffer, &buffer_len);
16
+
17
+ if (err == 0) {
18
+ // Re-encode the decoded bytes; the result must decode back identically.
19
+ size_t string_len = 4 * ((buffer_len + 2) / 3);
20
+ utf8_t *string = string_len > 0 ? malloc(string_len) : NULL;
21
+
22
+ size_t len = string_len;
23
+ err = base64_encode_utf8(buffer, buffer_len, string, &len);
24
+
25
+ assert(err == 0);
26
+ assert(len == string_len);
27
+
28
+ size_t roundtrip_len = buffer_len;
29
+ uint8_t *roundtrip = roundtrip_len > 0 ? malloc(roundtrip_len) : NULL;
30
+
31
+ err = base64_decode_utf8(string, string_len, roundtrip, &roundtrip_len);
32
+
33
+ assert(err == 0);
34
+ assert(roundtrip_len == buffer_len);
35
+
36
+ if (buffer_len > 0) {
37
+ assert(memcmp(roundtrip, buffer, buffer_len) == 0);
38
+ }
39
+
40
+ free(roundtrip);
41
+ free(string);
42
+ }
43
+
44
+ free(buffer);
45
+
46
+ return 0;
47
+ }