bare-url 2.0.8 → 2.0.9

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 (53) hide show
  1. package/CMakeLists.txt +3 -7
  2. package/package.json +3 -6
  3. package/prebuilds/android-arm/bare-url.bare +0 -0
  4. package/prebuilds/android-arm64/bare-url.bare +0 -0
  5. package/prebuilds/android-ia32/bare-url.bare +0 -0
  6. package/prebuilds/android-x64/bare-url.bare +0 -0
  7. package/prebuilds/win32-arm64/bare-url.bare +0 -0
  8. package/prebuilds/win32-x64/bare-url.bare +0 -0
  9. package/vendor/liburl/CMakeLists.txt +0 -81
  10. package/vendor/liburl/include/url/character-set.h +0 -41
  11. package/vendor/liburl/include/url/idna.h +0 -14
  12. package/vendor/liburl/include/url/infra.h +0 -141
  13. package/vendor/liburl/include/url/parse.h +0 -1406
  14. package/vendor/liburl/include/url/percent-encode.h +0 -567
  15. package/vendor/liburl/include/url/punycode.h +0 -21
  16. package/vendor/liburl/include/url/serialize.h +0 -91
  17. package/vendor/liburl/include/url/type.h +0 -61
  18. package/vendor/liburl/include/url.h +0 -147
  19. package/vendor/liburl/src/url.c +0 -42
  20. package/vendor/libutf/CMakeLists.txt +0 -93
  21. package/vendor/libutf/include/utf/string.h +0 -786
  22. package/vendor/libutf/include/utf.h +0 -132
  23. package/vendor/libutf/src/ascii/validate.c +0 -47
  24. package/vendor/libutf/src/endianness.c +0 -19
  25. package/vendor/libutf/src/endianness.h +0 -54
  26. package/vendor/libutf/src/latin1/convert-to-utf16.c +0 -37
  27. package/vendor/libutf/src/latin1/convert-to-utf32.c +0 -34
  28. package/vendor/libutf/src/latin1/convert-to-utf8.c +0 -58
  29. package/vendor/libutf/src/latin1/length-from-utf16.c +0 -26
  30. package/vendor/libutf/src/latin1/length-from-utf32.c +0 -26
  31. package/vendor/libutf/src/latin1/length-from-utf8.c +0 -34
  32. package/vendor/libutf/src/utf16/convert-to-latin1.c +0 -41
  33. package/vendor/libutf/src/utf16/convert-to-utf32.c +0 -56
  34. package/vendor/libutf/src/utf16/convert-to-utf8.c +0 -75
  35. package/vendor/libutf/src/utf16/length-from-latin1.c +0 -26
  36. package/vendor/libutf/src/utf16/length-from-utf32.c +0 -33
  37. package/vendor/libutf/src/utf16/length-from-utf8.c +0 -38
  38. package/vendor/libutf/src/utf16/validate.c +0 -53
  39. package/vendor/libutf/src/utf32/convert-to-latin1.c +0 -40
  40. package/vendor/libutf/src/utf32/convert-to-utf16.c +0 -56
  41. package/vendor/libutf/src/utf32/convert-to-utf8.c +0 -71
  42. package/vendor/libutf/src/utf32/length-from-latin1.c +0 -26
  43. package/vendor/libutf/src/utf32/length-from-utf16.c +0 -35
  44. package/vendor/libutf/src/utf32/length-from-utf8.c +0 -35
  45. package/vendor/libutf/src/utf32/validate.c +0 -39
  46. package/vendor/libutf/src/utf8/convert-to-latin1.c +0 -70
  47. package/vendor/libutf/src/utf8/convert-to-utf16.c +0 -95
  48. package/vendor/libutf/src/utf8/convert-to-utf32.c +0 -110
  49. package/vendor/libutf/src/utf8/length-from-latin1.c +0 -32
  50. package/vendor/libutf/src/utf8/length-from-utf16.c +0 -44
  51. package/vendor/libutf/src/utf8/length-from-utf32.c +0 -35
  52. package/vendor/libutf/src/utf8/string.c +0 -149
  53. package/vendor/libutf/src/utf8/validate.c +0 -107
@@ -1,1406 +0,0 @@
1
- #ifndef URL_PARSE_H
2
- #define URL_PARSE_H
3
-
4
- #include <assert.h>
5
- #include <stdbool.h>
6
- #include <stddef.h>
7
- #include <stdint.h>
8
- #include <stdlib.h>
9
- #include <utf.h>
10
- #include <utf/string.h>
11
-
12
- #include "../url.h"
13
- #include "character-set.h"
14
- #include "infra.h"
15
- #include "percent-encode.h"
16
- #include "serialize.h"
17
- #include "type.h"
18
-
19
- typedef enum {
20
- url_state_scheme_start = 1,
21
- url_state_scheme,
22
- url_state_no_scheme,
23
- url_state_special_relative_or_authority,
24
- url_state_path_or_authority,
25
- url_state_relative,
26
- url_state_relative_slash,
27
- url_state_special_authority_slashes,
28
- url_state_special_authority_ignore_slashes,
29
- url_state_authority,
30
- url_state_host,
31
- url_state_hostname,
32
- url_state_port,
33
- url_state_file,
34
- url_state_file_slash,
35
- url_state_file_host,
36
- url_state_path_start,
37
- url_state_path,
38
- url_state_opaque_path,
39
- url_state_query,
40
- url_state_fragment,
41
- } url_state_t;
42
-
43
- // https://url.spec.whatwg.org/#forbidden-host-code-point
44
- static url_character_set_t url__forbidden_host_character_set = {
45
- // 00 01 02 03 04 05 06 07
46
- 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
47
- // 08 09 0a 0b 0c 0d 0e 0f
48
- 0x00 | 0x02 | 0x04 | 0x00 | 0x00 | 0x20 | 0x00 | 0x00,
49
- // 10 11 12 13 14 15 16 17
50
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
51
- // 18 19 1a 1b 1c 1d 1e 1f
52
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
53
- // 20 21 22 23 24 25 26 27
54
- 0x01 | 0x00 | 0x00 | 0x08 | 0x00 | 0x00 | 0x00 | 0x00,
55
- // 28 29 2a 2b 2c 2d 2e 2f
56
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
57
- // 30 31 32 33 34 35 36 37
58
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
59
- // 38 39 3a 3b 3c 3d 3e 3f
60
- 0x00 | 0x00 | 0x04 | 0x00 | 0x10 | 0x00 | 0x40 | 0x80,
61
- // 40 41 42 43 44 45 46 47
62
- 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
63
- // 48 49 4a 4b 4c 4d 4e 4f
64
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
65
- // 50 51 52 53 54 55 56 57
66
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
67
- // 58 59 5a 5b 5c 5d 5e 5f
68
- 0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x40 | 0x00,
69
- // 60 61 62 63 64 65 66 67
70
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
71
- // 68 69 6a 6b 6c 6d 6e 6f
72
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
73
- // 70 71 72 73 74 75 76 77
74
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
75
- // 78 79 7a 7b 7c
76
- 0x00 | 0x00 | 0x00 | 0x00 | 0x10,
77
- };
78
-
79
- // https://url.spec.whatwg.org/#forbidden-domain-code-point
80
- static url_character_set_t url__forbidden_domain_character_set = {
81
- // 00 01 02 03 04 05 06 07
82
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
83
- // 08 09 0a 0b 0c 0d 0e 0f
84
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
85
- // 10 11 12 13 14 15 16 17
86
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
87
- // 18 19 1a 1b 1c 1d 1e 1f
88
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
89
- // 20 21 22 23 24 25 26 27
90
- 0x01 | 0x00 | 0x00 | 0x08 | 0x00 | 0x20 | 0x00 | 0x00,
91
- // 28 29 2a 2b 2c 2d 2e 2f
92
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
93
- // 30 31 32 33 34 35 36 37
94
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
95
- // 38 39 3a 3b 3c 3d 3e 3f
96
- 0x00 | 0x00 | 0x04 | 0x00 | 0x10 | 0x00 | 0x40 | 0x80,
97
- // 40 41 42 43 44 45 46 47
98
- 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
99
- // 48 49 4a 4b 4c 4d 4e 4f
100
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
101
- // 50 51 52 53 54 55 56 57
102
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
103
- // 58 59 5a 5b 5c 5d 5e 5f
104
- 0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x40 | 0x00,
105
- // 60 61 62 63 64 65 66 67
106
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
107
- // 68 69 6a 6b 6c 6d 6e 6f
108
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
109
- // 70 71 72 73 74 75 76 77
110
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
111
- // 78 79 7a 7b 7c
112
- 0x00 | 0x00 | 0x00 | 0x00 | 0x10,
113
- };
114
-
115
- static url_character_set_t url__scheme_character_set = {
116
- // 00 01 02 03 04 05 06 07
117
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
118
- // 08 09 0a 0b 0c 0d 0e 0f
119
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
120
- // 10 11 12 13 14 15 16 17
121
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
122
- // 18 19 1a 1b 1c 1d 1e 1f
123
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
124
- // 20 21 22 23 24 25 26 27
125
- 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
126
- // 28 29 2a 2b 2c 2d 2e 2f
127
- 0x00 | 0x00 | 0x00 | 0x08 | 0x00 | 0x20 | 0x40 | 0x00,
128
- // 30 31 32 33 34 35 36 37
129
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
130
- // 38 39 3a 3b 3c 3d 3e 3f
131
- 0x01 | 0x02 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
132
- // 40 41 42 43 44 45 46 47
133
- 0x00 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
134
- // 48 49 4a 4b 4c 4d 4e 4f
135
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
136
- // 50 51 52 53 54 55 56 57
137
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
138
- // 58 59 5a 5b 5c 5d 5e 5f
139
- 0x01 | 0x02 | 0x04 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
140
- // 60 61 62 63 64 65 66 67
141
- 0x00 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
142
- // 68 69 6a 6b 6c 6d 6e 6f
143
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
144
- // 70 71 72 73 74 75 76 77
145
- 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
146
- // 78 79 7a
147
- 0x01 | 0x02 | 0x04,
148
- };
149
-
150
- // https://url.spec.whatwg.org/#windows-drive-letter
151
- static inline bool
152
- url__is_windows_drive_letter (const utf8_string_view_t input) {
153
- return input.len == 2 && url__is_ascii_alpha(input.data[0]) && (input.data[1] == 0x3a || input.data[1] == 0x7c);
154
- }
155
-
156
- // https://url.spec.whatwg.org/#normalized-windows-drive-letter
157
- static inline bool
158
- url__is_normalized_windows_drive_letter (const utf8_string_view_t input) {
159
- return input.len == 2 && url__is_ascii_alpha(input.data[0]) && input.data[1] == 0x3a;
160
- }
161
-
162
- // https://url.spec.whatwg.org/#start-with-a-windows-drive-letter
163
- static inline bool
164
- url__starts_with_windows_drive_letter (const utf8_string_view_t input) {
165
- return (
166
- input.len >= 2 &&
167
- url__is_normalized_windows_drive_letter(utf8_string_view_substring(input, 0, 2)) &&
168
- (input.len == 2 || input.data[2] == 0x2f || input.data[2] == 0x5c || input.data[2] == 0x3f || input.data[2] == 0x23)
169
- );
170
- }
171
-
172
- // https://url.spec.whatwg.org/#shorten-a-urls-path
173
- static inline void
174
- url__shorten_path (url_t *url) {
175
- assert((url->flags & url_has_opaque_path) == 0);
176
-
177
- utf8_string_view_t path = url_get_path(url);
178
-
179
- size_t i = utf8_string_view_last_index_of_character(path, path.len - 1, '/');
180
-
181
- if (i == (size_t) -1) return;
182
-
183
- if (
184
- url->type == url_type_file &&
185
- i == 0 &&
186
- url__is_normalized_windows_drive_letter(utf8_string_view_substring(path, 1, path.len))
187
- ) {
188
- return;
189
- }
190
-
191
- url->href.len = url->components.path_start + i;
192
- }
193
-
194
- // https://url.spec.whatwg.org/#single-dot-path-segment
195
- static inline bool
196
- url__is_single_dot_path_segment (const utf8_string_view_t path) {
197
- size_t len = path.len;
198
- const utf8_t *data = path.data;
199
-
200
- // .
201
- if (len == 1) return data[0] == '.';
202
-
203
- // %2e
204
- return len == 3 && data[0] == '%' && data[1] == '2' && url__to_ascii_lowercase(data[2]) == 'e';
205
- }
206
-
207
- // https://url.spec.whatwg.org/#double-dot-path-segment
208
- static inline bool
209
- url__is_double_dot_path_segment (const utf8_string_view_t path) {
210
- size_t len = path.len;
211
- const utf8_t *data = path.data;
212
-
213
- // ..
214
- if (len == 2 && data[0] == '.' && data[0] == '.') {
215
- return true;
216
- }
217
-
218
- if (len == 4) {
219
- // .%2e
220
- if (data[0] == '.' && data[1] == '%' && data[2] == '2' && url__to_ascii_lowercase(data[3]) == 'e') {
221
- return true;
222
- }
223
-
224
- // %2e.
225
- if (data[0] == '%' && data[1] == '2' && url__to_ascii_lowercase(data[2]) == 'e' && data[3] == '.') {
226
- return true;
227
- }
228
- }
229
-
230
- // %2e%2e
231
- return (
232
- len == 6 &&
233
- data[0] == '%' && data[1] == '2' && url__to_ascii_lowercase(data[2]) == 'e' &&
234
- data[3] == '%' && data[4] == '2' && url__to_ascii_lowercase(data[5]) == 'e'
235
- );
236
- }
237
-
238
- // https://url.spec.whatwg.org/#ends-in-a-number-checker
239
- static inline bool
240
- url__ends_in_a_number (const utf8_string_view_t input) {
241
- size_t i = utf8_string_view_last_index_of_character(input, input.len - 1, '.');
242
-
243
- utf8_string_view_t last = utf8_string_view_substring(input, i + 1, input.len);
244
-
245
- if (utf8_string_view_empty(last)) {
246
- if (i + 1 == 0) return false;
247
-
248
- size_t j = utf8_string_view_last_index_of_character(input, i - 1, '.');
249
-
250
- last = utf8_string_view_substring(input, j + 1, i);
251
-
252
- if (utf8_string_view_empty(last)) return false;
253
- }
254
-
255
- if (last.len > 1 && last.data[0] == 0x30 && url__to_ascii_lowercase(last.data[1]) == 0x78) {
256
- last = utf8_string_view_substring(last, 2, last.len);
257
-
258
- for (size_t i = 0; i < last.len; i++) {
259
- if (!url__is_ascii_hex_digit(last.data[i])) return false;
260
- }
261
- } else {
262
- for (size_t i = 0; i < last.len; i++) {
263
- if (!url__is_ascii_digit(last.data[i])) return false;
264
- }
265
- }
266
-
267
- return true;
268
- }
269
-
270
- // https://url.spec.whatwg.org/#ipv4-number-parser
271
- static inline uint64_t
272
- url__parse_ipv4_number (utf8_string_view_t input) {
273
- if (utf8_string_view_empty(input)) goto err;
274
-
275
- uint8_t r = 10;
276
-
277
- if (input.len > 1 && input.data[0] == 0x30 && url__to_ascii_lowercase(input.data[1]) == 0x78) {
278
- input = utf8_string_view_substring(input, 2, input.len);
279
-
280
- if (utf8_string_view_empty(input)) goto err;
281
-
282
- r = 16;
283
- } else if (input.len > 1 && input.data[0] == 0x30) {
284
- input = utf8_string_view_substring(input, 1, input.len);
285
-
286
- if (utf8_string_view_empty(input)) goto err;
287
-
288
- r = 8;
289
- }
290
-
291
- uint64_t result = 0;
292
-
293
- for (size_t i = 0; i < input.len; i++) {
294
- utf8_t c = input.data[i];
295
-
296
- uint8_t value;
297
-
298
- if (url__is_ascii_digit(c)) {
299
- value = c - 0x30;
300
-
301
- if (value >= r) goto err;
302
- } else if (r == 16 && url__is_ascii_upper_hex_digit(c)) {
303
- value = c - 0x41 + 10;
304
- } else if (r == 16 && url__is_ascii_lower_hex_digit(c)) {
305
- value = c - 0x61 + 10;
306
- } else {
307
- goto err;
308
- }
309
-
310
- result = result * r + value;
311
- }
312
-
313
- return result;
314
-
315
- err:
316
- return (uint64_t) -1;
317
- }
318
-
319
- // https://url.spec.whatwg.org/#concept-ipv4-parser
320
- static inline int
321
- url__parse_ipv4 (utf8_string_view_t input, utf8_string_t *result) {
322
- uint32_t address = 0;
323
-
324
- uint8_t parts = 0;
325
-
326
- while (!utf8_string_view_empty(input)) {
327
- size_t i = utf8_string_view_index_of_character(input, 0, '.');
328
-
329
- utf8_string_view_t part = utf8_string_view_substring(input, 0, i);
330
-
331
- input = utf8_string_view_substring(input, i + 1, input.len);
332
-
333
- uint64_t value = url__parse_ipv4_number(part);
334
-
335
- if (value == (uint64_t) -1) goto err;
336
-
337
- if (i == (size_t) -1) {
338
- size_t bits = 32 - parts * 8;
339
-
340
- if (value > (1 << bits)) goto err;
341
-
342
- address = (address << bits) | value;
343
-
344
- break;
345
- }
346
-
347
- if (value > 255 || parts == 3) goto err;
348
-
349
- address = (address << 8) | value;
350
-
351
- parts++;
352
- }
353
-
354
- return url__serialize_ipv4(address, result);
355
-
356
- err:
357
- return -1;
358
- }
359
-
360
- // https://url.spec.whatwg.org/#concept-ipv6-parser
361
- static inline int
362
- url__parse_ipv6 (utf8_string_view_t input, utf8_string_t *result) {
363
- int err;
364
-
365
- if (utf8_string_view_empty(input)) goto err;
366
-
367
- uint16_t address[8] = {0};
368
-
369
- uint8_t piece_index = 0;
370
- uint8_t compress = (uint8_t) -1;
371
-
372
- const utf8_t *pointer = input.data;
373
- const utf8_t *eof = &input.data[input.len];
374
-
375
- if (input.data[0] == 0x3a) {
376
- if (input.len == 1 || input.data[1] != 0x3a) goto err;
377
-
378
- pointer += 2;
379
- compress = ++piece_index;
380
- }
381
-
382
- while (pointer != eof) {
383
- if (piece_index == 8) goto err;
384
-
385
- if (*pointer == 0x3a) {
386
- if (compress != (uint8_t) -1) goto err;
387
-
388
- pointer++;
389
- compress = ++piece_index;
390
- }
391
-
392
- uint16_t value = 0, length = 0;
393
-
394
- while (length < 4 && pointer != eof && url__is_ascii_hex_digit(*pointer)) {
395
- value = value * 0x10 + url__hex_decoded[*pointer];
396
-
397
- pointer++;
398
- length++;
399
- }
400
-
401
- if (pointer != eof && *pointer == 0x2e) {
402
- if (length == 0) goto err;
403
-
404
- pointer -= length;
405
-
406
- if (piece_index > 6) goto err;
407
-
408
- uint16_t numbers_seen = 0;
409
-
410
- while (pointer != eof) {
411
- uint16_t ipv4_piece = (uint16_t) -1;
412
-
413
- if (numbers_seen > 0) {
414
- if (*pointer == 0x2e && numbers_seen < 4) {
415
- pointer++;
416
- } else {
417
- goto err;
418
- }
419
- }
420
-
421
- if (pointer == eof || !url__is_ascii_digit(*pointer)) {
422
- goto err;
423
- }
424
-
425
- while (pointer != eof && url__is_ascii_digit(*pointer)) {
426
- uint8_t number = *pointer - 0x30;
427
-
428
- if (ipv4_piece == (uint16_t) -1) {
429
- ipv4_piece = number;
430
- } else if (ipv4_piece == 0) {
431
- goto err;
432
- } else {
433
- ipv4_piece = ipv4_piece * 10 + number;
434
- }
435
-
436
- if (ipv4_piece > 255) goto err;
437
-
438
- pointer++;
439
- }
440
-
441
- address[piece_index] = address[piece_index] * 0x100 + ipv4_piece;
442
-
443
- numbers_seen++;
444
-
445
- if (numbers_seen == 2 || numbers_seen == 4) piece_index++;
446
- }
447
-
448
- if (numbers_seen != 4) goto err;
449
-
450
- break;
451
- } else if (*pointer == 0x3a) {
452
- pointer++;
453
-
454
- if (pointer == eof) goto err;
455
- } else if (pointer != eof) {
456
- goto err;
457
- }
458
-
459
- address[piece_index] = value;
460
-
461
- piece_index++;
462
- }
463
-
464
- if (compress != (uint8_t) -1) {
465
- int8_t swaps = piece_index - compress;
466
-
467
- piece_index = 7;
468
-
469
- while (piece_index != 0 && swaps > 0) {
470
- uint16_t tmp = address[piece_index];
471
-
472
- address[piece_index] = address[compress + swaps - 1];
473
- address[compress + swaps - 1] = tmp;
474
-
475
- piece_index--;
476
- swaps--;
477
- }
478
- } else if (piece_index != 8) {
479
- goto err;
480
- }
481
-
482
- err = utf8_string_append_character(result, '[');
483
- if (err < 0) goto err;
484
-
485
- err = url__serialize_ipv6(address, result);
486
- if (err < 0) goto err;
487
-
488
- err = utf8_string_append_character(result, ']');
489
- if (err < 0) goto err;
490
-
491
- return 0;
492
-
493
- err:
494
- return -1;
495
- }
496
-
497
- // https://url.spec.whatwg.org/#concept-opaque-host-parser
498
- static inline int
499
- url__parse_opaque_host (const utf8_string_view_t input, utf8_string_t *result) {
500
- if (url__contains_from_character_set(url__forbidden_host_character_set, input)) {
501
- return -1;
502
- }
503
-
504
- return url__percent_encode_string(input, url__c0_control_percent_encode_set, result);
505
- }
506
-
507
- // https://url.spec.whatwg.org/#concept-host-parser
508
- static inline int
509
- url__parse_host (const utf8_string_view_t input, bool is_opaque, utf8_string_t *result) {
510
- int err;
511
-
512
- if (input.len > 0 && input.data[0] == 0x5b) {
513
- if (input.data[input.len - 1] != 0x5d) return -1;
514
-
515
- return url__parse_ipv6(utf8_string_view_substring(input, 1, input.len - 1), result);
516
- }
517
-
518
- if (is_opaque) return url__parse_opaque_host(input, result);
519
-
520
- assert(input.len != 0);
521
-
522
- if (!url__contains_from_character_set(url__forbidden_domain_character_set, input)) {
523
- err = utf8_string_append_view(result, input);
524
- if (err < 0) return err;
525
-
526
- return 0;
527
- }
528
-
529
- utf8_string_t domain;
530
- utf8_string_init(&domain);
531
-
532
- err = url__percent_decode_string(input, &domain);
533
- if (err < 0) goto err;
534
-
535
- // TODO Domain to ASCII
536
-
537
- utf8_string_t ascii_domain = domain;
538
-
539
- if (url__ends_in_a_number(utf8_string_view(&ascii_domain))) {
540
- err = url__parse_ipv4(utf8_string_view(&ascii_domain), result);
541
- if (err < 0) goto err;
542
- } else {
543
- err = utf8_string_append(result, &ascii_domain);
544
- if (err < 0) goto err;
545
- }
546
-
547
- utf8_string_destroy(&domain);
548
-
549
- return 0;
550
-
551
- err:
552
- utf8_string_destroy(&domain);
553
-
554
- return -1;
555
- }
556
-
557
- static inline int
558
- url__parse (url_t *url, const utf8_string_view_t input, const url_t *base) {
559
- int err;
560
-
561
- url_state_t state = url_state_scheme_start;
562
-
563
- utf8_string_t buffer;
564
- utf8_string_init(&buffer);
565
-
566
- err = utf8_string_reserve(&url->href, input.len);
567
- if (err < 0) goto err;
568
-
569
- bool at_sign_seen = false, inside_brackets = false, password_token_seen = false;
570
-
571
- for (size_t pointer = 0, n = input.len; pointer <= n; pointer++) {
572
- int16_t c = pointer < n ? input.data[pointer] : -1;
573
-
574
- switch (state) {
575
- // https://url.spec.whatwg.org/#scheme-start-state
576
- case url_state_scheme_start:
577
- if (url__is_ascii_alpha(c)) {
578
- state = url_state_scheme;
579
- } else {
580
- state = url_state_no_scheme;
581
- pointer--;
582
- }
583
- break;
584
-
585
- // https://url.spec.whatwg.org/#scheme-state
586
- case url_state_scheme:
587
- while (url__is_in_character_set(url__scheme_character_set, c)) {
588
- c = pointer + 1 < n ? input.data[++pointer] : -1;
589
- }
590
-
591
- if (c == 0x3a) {
592
- url_type_t type = url__type(utf8_string_view_substring(input, 0, pointer));
593
-
594
- err = utf8_string_append_view(&url->href, utf8_string_view_substring(input, 0, pointer + 1 /* : */));
595
- if (err < 0) goto err;
596
-
597
- if (type == url_type_opaque) {
598
- for (size_t i = 0, n = url->href.len - 1 /* : */; i < n; i++) {
599
- url->href.data[i] = url__to_ascii_lowercase(url->href.data[i]);
600
- }
601
-
602
- type = url__type(utf8_string_substring(&url->href, 0, url->href.len - 1 /* : */));
603
- }
604
-
605
- url->type = type;
606
-
607
- url->components.scheme_end = url->href.len - 1 /* : */;
608
-
609
- utf8_string_view_t scheme = url_get_scheme(url);
610
-
611
- if (url->type == url_type_file) {
612
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
613
- if (err < 0) goto err;
614
-
615
- url->components.username_end = url->href.len;
616
-
617
- state = url_state_file;
618
- } else if (url__is_special(url)) {
619
- if (base != NULL && url->type == base->type) {
620
- assert(url__is_special(base));
621
-
622
- state = url_state_special_relative_or_authority;
623
- } else {
624
- state = url_state_special_authority_slashes;
625
- }
626
- } else if (pointer + 1 < input.len && input.data[pointer + 1] == 0x2f) {
627
- url->components.username_end = url->href.len;
628
-
629
- state = url_state_path_or_authority;
630
- pointer++;
631
- } else {
632
- url->flags |= url_has_opaque_path;
633
-
634
- url->components.username_end = url->href.len;
635
- url->components.host_start = url->href.len;
636
- url->components.host_end = url->href.len;
637
- url->components.path_start = url->href.len;
638
-
639
- state = url_state_opaque_path;
640
- }
641
- } else {
642
- state = url_state_no_scheme;
643
- pointer = -1;
644
- }
645
- break;
646
-
647
- // https://url.spec.whatwg.org/#no-scheme-state
648
- case url_state_no_scheme:
649
- if (base == NULL) goto err;
650
-
651
- if (base->flags & url_has_opaque_path) {
652
- if (c != 0x23) goto err;
653
-
654
- err = utf8_string_append_view(&url->href, url_get_scheme(base));
655
- if (err < 0) goto err;
656
-
657
- url->type = base->type;
658
-
659
- url->components.scheme_end = url->href.len;
660
- url->components.host_start = url->href.len;
661
- url->components.host_end = url->href.len;
662
- url->components.username_end = url->href.len;
663
-
664
- err = utf8_string_append_character(&url->href, ':');
665
- if (err < 0) goto err;
666
-
667
- url->components.path_start = url->href.len;
668
-
669
- err = utf8_string_append_view(&url->href, url_get_path(base));
670
- if (err < 0) goto err;
671
-
672
- utf8_string_view_t query = url_get_query(base);
673
-
674
- if (!utf8_string_view_empty(query)) {
675
- err = utf8_string_append_character(&url->href, '?');
676
- if (err < 0) goto err;
677
-
678
- url->components.query_start = url->href.len;
679
-
680
- err = utf8_string_append_view(&url->href, query);
681
- if (err < 0) goto err;
682
- } else {
683
- url->components.query_start = url->href.len + 1;
684
- }
685
-
686
- err = utf8_string_append_character(&url->href, '#');
687
- if (err < 0) goto err;
688
-
689
- url->components.fragment_start = url->href.len;
690
-
691
- state = url_state_fragment;
692
- } else if (base->type != url_type_file) {
693
- state = url_state_relative;
694
- pointer--;
695
- } else {
696
- err = utf8_string_append_literal(&url->href, (utf8_t *) "file", 4);
697
- if (err < 0) goto err;
698
-
699
- url->type = url_type_file;
700
-
701
- url->components.scheme_end = url->href.len;
702
-
703
- err = utf8_string_append_literal(&url->href, (utf8_t *) "://", 3);
704
- if (err < 0) goto err;
705
-
706
- url->components.username_end = url->href.len;
707
-
708
- state = url_state_file;
709
- pointer--;
710
- }
711
- break;
712
-
713
- // https://url.spec.whatwg.org/#special-relative-or-authority-state
714
- case url_state_special_relative_or_authority:
715
- if (c == 0x2f && pointer + 1 < input.len && input.data[pointer + 1] == 0x2f) {
716
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
717
- if (err < 0) goto err;
718
-
719
- url->components.username_end = url->href.len;
720
-
721
- state = url_state_special_authority_ignore_slashes;
722
- pointer++;
723
- } else {
724
- state = url_state_relative;
725
- pointer--;
726
- }
727
- break;
728
-
729
- // https://url.spec.whatwg.org/#path-or-authority-state
730
- case url_state_path_or_authority:
731
- if (c == 0x2f) {
732
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
733
- if (err < 0) goto err;
734
-
735
- url->components.username_end = url->href.len;
736
-
737
- state = url_state_authority;
738
- } else {
739
- url->components.username_end = url->href.len;
740
- url->components.host_start = url->href.len;
741
- url->components.host_end = url->href.len;
742
- url->components.path_start = url->href.len;
743
-
744
- state = url_state_path;
745
- pointer--;
746
- }
747
- break;
748
-
749
- // https://url.spec.whatwg.org/#relative-state
750
- case url_state_relative:
751
- assert(base->type != url_type_file);
752
-
753
- if (url->components.scheme_end == 0) {
754
- err = utf8_string_append_view(&url->href, url_get_scheme(base));
755
- if (err < 0) goto err;
756
-
757
- url->type = base->type;
758
-
759
- url->components.scheme_end = url->href.len;
760
-
761
- err = utf8_string_append_character(&url->href, ':');
762
- if (err < 0) goto err;
763
- }
764
-
765
- if (c == 0x2f) {
766
- if (url->type != url_type_opaque) {
767
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
768
- if (err < 0) goto err;
769
- }
770
-
771
- url->components.username_end = url->href.len;
772
-
773
- state = url_state_relative_slash;
774
- } else if (url__is_special(url) && c == 0x5c) {
775
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
776
- if (err < 0) goto err;
777
-
778
- url->components.username_end = url->href.len;
779
-
780
- state = url_state_relative_slash;
781
- } else {
782
- utf8_string_view_t host = url_get_host(base);
783
-
784
- if (!utf8_string_view_empty(host)) {
785
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
786
- if (err < 0) goto err;
787
-
788
- utf8_string_view_t username = url_get_username(base);
789
-
790
- if (!utf8_string_view_empty(username)) {
791
- err = utf8_string_append_view(&url->href, username);
792
- if (err < 0) goto err;
793
-
794
- url->components.username_end = url->href.len;
795
-
796
- utf8_string_view_t password = url_get_password(base);
797
-
798
- if (!utf8_string_view_empty(password)) {
799
- err = utf8_string_append_character(&url->href, ':');
800
- if (err < 0) goto err;
801
-
802
- err = utf8_string_append_view(&url->href, password);
803
- if (err < 0) goto err;
804
- }
805
-
806
- err = utf8_string_append_character(&url->href, '@');
807
- if (err < 0) goto err;
808
- } else {
809
- url->components.username_end = url->href.len;
810
- }
811
-
812
- url->components.host_start = url->href.len;
813
-
814
- err = utf8_string_append_view(&url->href, host);
815
- if (err < 0) goto err;
816
-
817
- url->components.host_end = url->href.len;
818
-
819
- utf8_string_view_t port = url_get_port(base);
820
-
821
- if (!utf8_string_view_empty(port)) {
822
- err = utf8_string_append_character(&url->href, ':');
823
- if (err < 0) goto err;
824
-
825
- err = utf8_string_append_view(&url->href, port);
826
- if (err < 0) goto err;
827
-
828
- url->components.port = base->components.port;
829
- }
830
- } else {
831
- if (base->components.scheme_end + 3 /* :// */ == base->components.username_end) {
832
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
833
- if (err < 0) goto err;
834
- }
835
-
836
- url->components.username_end = url->href.len;
837
- url->components.host_start = url->href.len;
838
- url->components.host_end = url->href.len;
839
- }
840
-
841
- url->components.path_start = url->href.len;
842
-
843
- err = utf8_string_append_view(&url->href, url_get_path(base));
844
- if (err < 0) goto err;
845
-
846
- if (c == 0x3f) {
847
- state = url_state_query;
848
- } else if (c == 0x23) {
849
- url->components.query_start = url->href.len + 1;
850
-
851
- err = utf8_string_append_character(&url->href, '#');
852
- if (err < 0) goto err;
853
-
854
- url->components.fragment_start = url->href.len;
855
-
856
- state = url_state_fragment;
857
- } else if (c != -1) {
858
- url__shorten_path(url);
859
-
860
- state = url_state_path;
861
- pointer--;
862
- } else {
863
- utf8_string_view_t query = url_get_query(base);
864
-
865
- if (!utf8_string_view_empty(query)) {
866
- err = utf8_string_append_character(&url->href, '?');
867
- if (err < 0) goto err;
868
-
869
- url->components.query_start = url->href.len;
870
-
871
- err = utf8_string_append_view(&url->href, query);
872
- if (err < 0) goto err;
873
- } else {
874
- url->components.query_start = url->href.len + 1;
875
- }
876
- }
877
- }
878
- break;
879
-
880
- // https://url.spec.whatwg.org/#relative-slash-state
881
- case url_state_relative_slash:
882
- if (url__is_special(url) && (c == 0x2f || c == 0x5c)) {
883
- state = url_state_special_authority_ignore_slashes;
884
- } else if (c == 0x2f) {
885
- state = url_state_authority;
886
- } else {
887
- utf8_string_view_t host = url_get_host(base);
888
-
889
- if (!utf8_string_view_empty(host)) {
890
- if (url->type == url_type_opaque) {
891
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
892
- if (err < 0) goto err;
893
- }
894
-
895
- utf8_string_view_t username = url_get_username(base);
896
-
897
- if (!utf8_string_view_empty(username)) {
898
- err = utf8_string_append_view(&url->href, username);
899
- if (err < 0) goto err;
900
-
901
- url->components.username_end = url->href.len;
902
-
903
- utf8_string_view_t password = url_get_password(base);
904
-
905
- if (!utf8_string_view_empty(password)) {
906
- err = utf8_string_append_character(&url->href, ':');
907
- if (err < 0) goto err;
908
-
909
- err = utf8_string_append_view(&url->href, password);
910
- if (err < 0) goto err;
911
- }
912
-
913
- err = utf8_string_append_character(&url->href, '@');
914
- if (err < 0) goto err;
915
- } else {
916
- url->components.username_end = url->href.len;
917
- }
918
-
919
- url->components.host_start = url->href.len;
920
-
921
- err = utf8_string_append_view(&url->href, host);
922
- if (err < 0) goto err;
923
-
924
- url->components.host_end = url->href.len;
925
-
926
- utf8_string_view_t port = url_get_port(base);
927
-
928
- if (!utf8_string_view_empty(port)) {
929
- err = utf8_string_append_character(&url->href, ':');
930
- if (err < 0) goto err;
931
-
932
- err = utf8_string_append_view(&url->href, url_get_port(base));
933
- if (err < 0) goto err;
934
- }
935
- } else {
936
- if (url->type == url_type_opaque && base->components.scheme_end + 3 /* :// */ == base->components.username_end) {
937
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
938
- if (err < 0) goto err;
939
- }
940
-
941
- url->components.username_end = url->href.len;
942
- url->components.host_start = url->href.len;
943
- url->components.host_end = url->href.len;
944
- }
945
-
946
- url->components.path_start = url->href.len;
947
-
948
- state = url_state_path;
949
- pointer--;
950
- }
951
- break;
952
-
953
- // https://url.spec.whatwg.org/#special-authority-slashes-state
954
- case url_state_special_authority_slashes:
955
- state = url_state_special_authority_ignore_slashes;
956
-
957
- if (c == 0x2f && pointer + 1 < input.len && input.data[pointer + 1] == 0x2f) {
958
- err = utf8_string_append_literal(&url->href, (utf8_t *) "//", 2);
959
- if (err < 0) goto err;
960
-
961
- url->components.username_end = url->href.len;
962
-
963
- pointer++;
964
- } else {
965
- pointer--;
966
- }
967
- break;
968
-
969
- // https://url.spec.whatwg.org/#special-authority-ignore-slashes-state
970
- case url_state_special_authority_ignore_slashes:
971
- if (c != 0x2f && c != 0x5c) {
972
- state = url_state_authority;
973
- pointer--;
974
- }
975
- break;
976
-
977
- // https://url.spec.whatwg.org/#authority-state
978
- case url_state_authority:
979
- if (c == 0x40) {
980
- if (at_sign_seen) {
981
- err = utf8_string_prepend_literal(&buffer, (utf8_t *) "%40", 3);
982
- if (err < 0) goto err;
983
- }
984
-
985
- at_sign_seen = true;
986
-
987
- for (size_t i = 0, n = buffer.len; i < n; i++) {
988
- utf8_t c = buffer.data[i];
989
-
990
- if (c == 0x3a && !password_token_seen) {
991
- password_token_seen = true;
992
-
993
- url->components.username_end = url->href.len;
994
-
995
- err = utf8_string_append_character(&url->href, ':');
996
- if (err < 0) goto err;
997
-
998
- continue;
999
- }
1000
-
1001
- err = url__percent_encode_character(c, url__userinfo_percent_encode_set, &url->href);
1002
- if (err < 0) goto err;
1003
- }
1004
-
1005
- if (!password_token_seen) {
1006
- url->components.username_end = url->href.len;
1007
- }
1008
-
1009
- err = utf8_string_append_character(&url->href, '@');
1010
- if (err < 0) goto err;
1011
-
1012
- utf8_string_clear(&buffer);
1013
- } else if (
1014
- (c == -1 || c == 0x2f || c == 0x3f || c == 0x23) ||
1015
- (url__is_special(url) && c == 0x5c)
1016
- ) {
1017
- if (at_sign_seen && utf8_string_empty(&buffer)) goto err;
1018
-
1019
- pointer -= buffer.len + 1;
1020
-
1021
- utf8_string_clear(&buffer);
1022
-
1023
- state = url_state_host;
1024
- } else {
1025
- err = utf8_string_append_character(&buffer, c);
1026
- if (err < 0) goto err;
1027
- }
1028
- break;
1029
-
1030
- // https://url.spec.whatwg.org/#host-state
1031
- case url_state_host:
1032
- // https://url.spec.whatwg.org/#hostname-state
1033
- case url_state_hostname:
1034
- if (c == 0x3a && !inside_brackets) {
1035
- if (utf8_string_empty(&buffer)) goto err;
1036
-
1037
- uint32_t host_start = url->href.len;
1038
-
1039
- err = url__parse_host(utf8_string_view(&buffer), !url__is_special(url), &url->href);
1040
- if (err < 0) goto err;
1041
-
1042
- url->components.host_start = host_start;
1043
- url->components.host_end = url->href.len;
1044
-
1045
- utf8_string_clear(&buffer);
1046
-
1047
- state = url_state_port;
1048
- } else if (
1049
- (c == -1 || c == 0x2f || c == 0x3f || c == 0x23) ||
1050
- (url__is_special(url) && c == 0x5c)
1051
- ) {
1052
- pointer--;
1053
-
1054
- if (url__is_special(url) && utf8_string_empty(&buffer)) goto err;
1055
-
1056
- uint32_t host_start = url->href.len;
1057
-
1058
- err = url__parse_host(utf8_string_view(&buffer), !url__is_special(url), &url->href);
1059
- if (err < 0) goto err;
1060
-
1061
- url->components.host_start = host_start;
1062
- url->components.host_end = url->href.len;
1063
-
1064
- utf8_string_clear(&buffer);
1065
-
1066
- url->components.path_start = url->href.len;
1067
-
1068
- state = url_state_path_start;
1069
- } else {
1070
- if (c == 0x5b) inside_brackets = true;
1071
- else if (c == 0x5d) inside_brackets = false;
1072
-
1073
- err = utf8_string_append_character(&buffer, c);
1074
- if (err < 0) goto err;
1075
- }
1076
- break;
1077
-
1078
- // https://url.spec.whatwg.org/#port-state
1079
- case url_state_port:
1080
- if (url__is_ascii_digit(c)) {
1081
- err = utf8_string_append_character(&buffer, c);
1082
- if (err < 0) goto err;
1083
- } else if (
1084
- (c == -1 || c == 0x2f || c == 0x3f || c == 0x23) ||
1085
- (url__is_special(url) && c == 0x5c)
1086
- ) {
1087
- if (!utf8_string_empty(&buffer)) {
1088
- uint32_t port = 0;
1089
-
1090
- for (size_t i = 0, n = buffer.len; i < n; i++) {
1091
- port = port * 10 + (buffer.data[i] - 0x30);
1092
- }
1093
-
1094
- if (port > UINT16_MAX) goto err;
1095
-
1096
- uint32_t default_port = url__default_port(url->type);
1097
-
1098
- if (port == default_port) {
1099
- url->components.port = (uint32_t) -1;
1100
- } else {
1101
- err = utf8_string_append_character(&url->href, ':');
1102
- if (err < 0) goto err;
1103
-
1104
- err = utf8_string_append(&url->href, &buffer);
1105
- if (err < 0) goto err;
1106
-
1107
- url->components.port = port;
1108
- }
1109
-
1110
- utf8_string_clear(&buffer);
1111
- }
1112
-
1113
- url->components.path_start = url->href.len;
1114
-
1115
- state = url_state_path_start;
1116
- pointer--;
1117
- } else {
1118
- goto err;
1119
- }
1120
- break;
1121
-
1122
- // https://url.spec.whatwg.org/#file-state
1123
- case url_state_file:
1124
- url->components.host_start = url->href.len;
1125
-
1126
- if (c == 0x2f || c == 0x5c) {
1127
- state = url_state_file_slash;
1128
- } else if (base != NULL && base->type == url_type_file) {
1129
- err = utf8_string_append_view(&url->href, url_get_host(base));
1130
- if (err < 0) goto err;
1131
-
1132
- url->components.host_end = url->href.len;
1133
-
1134
- url->components.path_start = url->href.len;
1135
-
1136
- err = utf8_string_append_view(&url->href, url_get_path(base));
1137
- if (err < 0) goto err;
1138
-
1139
- if (c == 0x3f) {
1140
- state = url_state_query;
1141
- } else if (c == 0x23) {
1142
- url->components.query_start = url->href.len + 1;
1143
-
1144
- err = utf8_string_append_character(&url->href, '#');
1145
- if (err < 0) goto err;
1146
-
1147
- url->components.fragment_start = url->href.len;
1148
-
1149
- state = url_state_fragment;
1150
- } else if (c != -1) {
1151
- if (!url__starts_with_windows_drive_letter(utf8_string_view_substring(input, pointer, input.len))) {
1152
- url__shorten_path(url);
1153
- } else {
1154
- url->href.len = url->components.path_start;
1155
- }
1156
-
1157
- state = url_state_path;
1158
- pointer--;
1159
- } else {
1160
- utf8_string_view_t query = url_get_query(base);
1161
-
1162
- if (!utf8_string_view_empty(query)) {
1163
- err = utf8_string_append_character(&url->href, '?');
1164
- if (err < 0) goto err;
1165
-
1166
- url->components.query_start = url->href.len;
1167
-
1168
- err = utf8_string_append_view(&url->href, query);
1169
- if (err < 0) goto err;
1170
- } else {
1171
- url->components.query_start = url->href.len + 1;
1172
- }
1173
- }
1174
- } else {
1175
- url->components.host_end = url->href.len;
1176
- url->components.path_start = url->href.len;
1177
-
1178
- state = url_state_path;
1179
- pointer--;
1180
- }
1181
- break;
1182
-
1183
- // https://url.spec.whatwg.org/#file-slash-state
1184
- case url_state_file_slash:
1185
- if (c == 0x2f || c == 0x5c) {
1186
- state = url_state_file_host;
1187
- } else {
1188
- if (base != NULL && base->type == url_type_file) {
1189
- err = utf8_string_append_view(&url->href, url_get_host(base));
1190
- if (err < 0) goto err;
1191
-
1192
- url->components.host_end = url->href.len;
1193
-
1194
- url->components.path_start = url->href.len;
1195
-
1196
- if (!url__starts_with_windows_drive_letter(utf8_string_view_substring(input, pointer, input.len))) {
1197
- utf8_string_view_t path = url_get_path(base);
1198
-
1199
- size_t i = utf8_string_view_index_of_character(path, 1, '/');
1200
-
1201
- if (i != (size_t) -1 && url__is_normalized_windows_drive_letter(utf8_string_view_substring(path, 1, i))) {
1202
- err = utf8_string_append_view(&url->href, utf8_string_view_substring(path, 0, i));
1203
- if (err < 0) goto err;
1204
- }
1205
- }
1206
- } else {
1207
- url->components.host_end = url->href.len;
1208
- url->components.path_start = url->href.len;
1209
- }
1210
-
1211
- state = url_state_path;
1212
- pointer--;
1213
- }
1214
- break;
1215
-
1216
- // https://url.spec.whatwg.org/#file-host-state
1217
- case url_state_file_host:
1218
- if (c == -1 || c == 0x2f || c == 0x5c || c == 0x3f || c == 0x23) {
1219
- pointer--;
1220
-
1221
- if (url__is_windows_drive_letter(utf8_string_view(&buffer))) {
1222
- url->components.host_start = url->href.len;
1223
- url->components.host_end = url->href.len;
1224
-
1225
- url->components.path_start = url->href.len;
1226
-
1227
- state = url_state_path;
1228
- } else {
1229
- url->components.host_start = url->href.len;
1230
-
1231
- if (utf8_string_empty(&buffer)) {
1232
- url->components.host_end = url->href.len;
1233
- } else {
1234
- err = url__parse_host(utf8_string_view(&buffer), !url__is_special(url), &url->href);
1235
- if (err < 0) goto err;
1236
-
1237
- url->components.host_end = url->href.len;
1238
-
1239
- utf8_string_clear(&buffer);
1240
- }
1241
-
1242
- url->components.path_start = url->href.len;
1243
-
1244
- state = url_state_path_start;
1245
- }
1246
- } else {
1247
- err = utf8_string_append_character(&buffer, c);
1248
- if (err < 0) goto err;
1249
- }
1250
- break;
1251
-
1252
- // https://url.spec.whatwg.org/#path-start-state
1253
- case url_state_path_start:
1254
- if (url__is_special(url)) {
1255
- state = url_state_path;
1256
-
1257
- if (c != 0x2f && c != 0x5c) pointer--;
1258
- } else if (c == 0x3f) {
1259
- state = url_state_query;
1260
- } else if (c == 0x23) {
1261
- url->components.query_start = url->href.len + 1;
1262
-
1263
- err = utf8_string_append_character(&url->href, '#');
1264
- if (err < 0) goto err;
1265
-
1266
- url->components.fragment_start = url->href.len;
1267
-
1268
- state = url_state_fragment;
1269
- } else if (c != -1) {
1270
- state = url_state_path;
1271
-
1272
- if (c != 0x2f) pointer--;
1273
- }
1274
- break;
1275
-
1276
- // https://url.spec.whatwg.org/#path-state
1277
- case url_state_path:
1278
- if (
1279
- (c == -1 || c == 0x2f) ||
1280
- (url__is_special(url) && c == 0x5c) ||
1281
- (c == 0x3f || c == 0x23)
1282
- ) {
1283
- utf8_string_view_t segment = utf8_string_view(&buffer);
1284
-
1285
- if (url__is_double_dot_path_segment(segment)) {
1286
- url__shorten_path(url);
1287
-
1288
- if (c != 0x2f && !(url__is_special(url) && c == 0x5c)) {
1289
- err = utf8_string_append_character(&url->href, '/');
1290
- if (err < 0) goto err;
1291
- }
1292
- } else if (url__is_single_dot_path_segment(segment)) {
1293
- if (c != 0x2f && !(url__is_special(url) && c == 0x5c)) {
1294
- err = utf8_string_append_character(&url->href, '/');
1295
- if (err < 0) goto err;
1296
- }
1297
- } else {
1298
- if (
1299
- url->type == url_type_file &&
1300
- utf8_string_view_empty(url_get_path(url)) &&
1301
- url__is_windows_drive_letter(segment)
1302
- ) {
1303
- buffer.data[1] = ':';
1304
- }
1305
-
1306
- err = utf8_string_append_character(&url->href, '/');
1307
- if (err < 0) goto err;
1308
-
1309
- err = utf8_string_append(&url->href, &buffer);
1310
- if (err < 0) goto err;
1311
- }
1312
-
1313
- utf8_string_clear(&buffer);
1314
-
1315
- if (c == 0x3f) {
1316
- state = url_state_query;
1317
- } else if (c == 0x23) {
1318
- url->components.query_start = url->href.len + 1;
1319
-
1320
- err = utf8_string_append_character(&url->href, '#');
1321
- if (err < 0) goto err;
1322
-
1323
- url->components.fragment_start = url->href.len;
1324
-
1325
- state = url_state_fragment;
1326
- }
1327
- } else {
1328
- err = url__percent_encode_character(c, url__path_percent_encode_set, &buffer);
1329
- if (err < 0) goto err;
1330
- }
1331
- break;
1332
-
1333
- // https://url.spec.whatwg.org/#cannot-be-a-base-url-path-state
1334
- case url_state_opaque_path:
1335
- if (c == 0x3f) {
1336
- state = url_state_query;
1337
- } else if (c == 0x23) {
1338
- url->components.query_start = url->href.len + 1;
1339
-
1340
- err = utf8_string_append_character(&url->href, '#');
1341
- if (err < 0) goto err;
1342
-
1343
- url->components.fragment_start = url->href.len;
1344
-
1345
- state = url_state_fragment;
1346
- } else if (c != -1) {
1347
- err = url__percent_encode_character(c, url__c0_control_percent_encode_set, &url->href);
1348
- if (err < 0) goto err;
1349
- }
1350
- break;
1351
-
1352
- // https://url.spec.whatwg.org/#query-state
1353
- case url_state_query:
1354
- if (c == 0x23 || c == -1) {
1355
- err = utf8_string_append_character(&url->href, '?');
1356
- if (err < 0) goto err;
1357
-
1358
- url_character_set_t *query_percent_encode_set = url__is_special(url)
1359
- ? &url__special_query_percent_encode_set
1360
- : &url__query_percent_encode_set;
1361
-
1362
- url->components.query_start = url->href.len;
1363
-
1364
- err = url__percent_encode_string(utf8_string_view(&buffer), *query_percent_encode_set, &url->href);
1365
- if (err < 0) goto err;
1366
-
1367
- utf8_string_clear(&buffer);
1368
-
1369
- url->components.fragment_start = url->href.len + 1;
1370
-
1371
- if (c == 0x23) {
1372
- err = utf8_string_append_character(&url->href, '#');
1373
- if (err < 0) goto err;
1374
-
1375
- state = url_state_fragment;
1376
- }
1377
- } else if (c != -1) {
1378
- err = utf8_string_append_character(&buffer, c);
1379
- if (err < 0) goto err;
1380
- }
1381
- break;
1382
-
1383
- // https://url.spec.whatwg.org/#fragment-state
1384
- case url_state_fragment:
1385
- // Optimization: The fragment is everything from the current position
1386
- // until the end of the string.
1387
-
1388
- err = url__percent_encode_string(utf8_string_view_substring(input, pointer, input.len), url__fragment_percent_encode_set, &url->href);
1389
- if (err < 0) goto err;
1390
-
1391
- goto done;
1392
- }
1393
- }
1394
-
1395
- done:
1396
- utf8_string_destroy(&buffer);
1397
-
1398
- return 0;
1399
-
1400
- err:
1401
- utf8_string_destroy(&buffer);
1402
-
1403
- return -1;
1404
- }
1405
-
1406
- #endif // URL_PARSE_H