Coverage Report

Created: 2025-06-20 06:37

/src/libgit2/deps/llhttp/api.c
Line
Count
Source (jump to first uncovered line)
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <string.h>
4
5
#include "llhttp.h"
6
7
#define CALLBACK_MAYBE(PARSER, NAME)                                          \
8
0
  do {                                                                        \
9
0
    const llhttp_settings_t* settings;                                        \
10
0
    settings = (const llhttp_settings_t*) (PARSER)->settings;                 \
11
0
    if (settings == NULL || settings->NAME == NULL) {                         \
12
0
      err = 0;                                                                \
13
0
      break;                                                                  \
14
0
    }                                                                         \
15
0
    err = settings->NAME((PARSER));                                           \
16
0
  } while (0)
17
18
#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN)                         \
19
0
  do {                                                                        \
20
0
    const llhttp_settings_t* settings;                                        \
21
0
    settings = (const llhttp_settings_t*) (PARSER)->settings;                 \
22
0
    if (settings == NULL || settings->NAME == NULL) {                         \
23
0
      err = 0;                                                                \
24
0
      break;                                                                  \
25
0
    }                                                                         \
26
0
    err = settings->NAME((PARSER), (START), (LEN));                           \
27
0
    if (err == -1) {                                                          \
28
0
      err = HPE_USER;                                                         \
29
0
      llhttp_set_error_reason((PARSER), "Span callback error in " #NAME);     \
30
0
    }                                                                         \
31
0
  } while (0)
32
33
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
34
0
                 const llhttp_settings_t* settings) {
35
0
  llhttp__internal_init(parser);
36
37
0
  parser->type = type;
38
0
  parser->settings = (void*) settings;
39
0
}
40
41
42
#if defined(__wasm__)
43
44
extern int wasm_on_message_begin(llhttp_t * p);
45
extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
46
extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
47
extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
48
extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
49
extern int wasm_on_headers_complete(llhttp_t * p, int status_code,
50
                                    uint8_t upgrade, int should_keep_alive);
51
extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
52
extern int wasm_on_message_complete(llhttp_t * p);
53
54
static int wasm_on_headers_complete_wrap(llhttp_t* p) {
55
  return wasm_on_headers_complete(p, p->status_code, p->upgrade,
56
                                  llhttp_should_keep_alive(p));
57
}
58
59
const llhttp_settings_t wasm_settings = {
60
  wasm_on_message_begin,
61
  wasm_on_url,
62
  wasm_on_status,
63
  NULL,
64
  NULL,
65
  wasm_on_header_field,
66
  wasm_on_header_value,
67
  NULL,
68
  NULL,
69
  wasm_on_headers_complete_wrap,
70
  wasm_on_body,
71
  wasm_on_message_complete,
72
  NULL,
73
  NULL,
74
  NULL,
75
  NULL,
76
  NULL,
77
  NULL,
78
  NULL,
79
  NULL,
80
  NULL,
81
  NULL,
82
  NULL,
83
};
84
85
86
llhttp_t* llhttp_alloc(llhttp_type_t type) {
87
  llhttp_t* parser = malloc(sizeof(llhttp_t));
88
  llhttp_init(parser, type, &wasm_settings);
89
  return parser;
90
}
91
92
void llhttp_free(llhttp_t* parser) {
93
  free(parser);
94
}
95
96
#endif  /* defined(__wasm__) */
97
98
/* Some getters required to get stuff from the parser */
99
100
0
uint8_t llhttp_get_type(llhttp_t* parser) {
101
0
  return parser->type;
102
0
}
103
104
0
uint8_t llhttp_get_http_major(llhttp_t* parser) {
105
0
  return parser->http_major;
106
0
}
107
108
0
uint8_t llhttp_get_http_minor(llhttp_t* parser) {
109
0
  return parser->http_minor;
110
0
}
111
112
0
uint8_t llhttp_get_method(llhttp_t* parser) {
113
0
  return parser->method;
114
0
}
115
116
0
int llhttp_get_status_code(llhttp_t* parser) {
117
0
  return parser->status_code;
118
0
}
119
120
0
uint8_t llhttp_get_upgrade(llhttp_t* parser) {
121
0
  return parser->upgrade;
122
0
}
123
124
125
0
void llhttp_reset(llhttp_t* parser) {
126
0
  llhttp_type_t type = parser->type;
127
0
  const llhttp_settings_t* settings = parser->settings;
128
0
  void* data = parser->data;
129
0
  uint16_t lenient_flags = parser->lenient_flags;
130
131
0
  llhttp__internal_init(parser);
132
133
0
  parser->type = type;
134
0
  parser->settings = (void*) settings;
135
0
  parser->data = data;
136
0
  parser->lenient_flags = lenient_flags;
137
0
}
138
139
140
0
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
141
0
  return llhttp__internal_execute(parser, data, data + len);
142
0
}
143
144
145
0
void llhttp_settings_init(llhttp_settings_t* settings) {
146
0
  memset(settings, 0, sizeof(*settings));
147
0
}
148
149
150
0
llhttp_errno_t llhttp_finish(llhttp_t* parser) {
151
0
  int err;
152
153
  /* We're in an error state. Don't bother doing anything. */
154
0
  if (parser->error != 0) {
155
0
    return 0;
156
0
  }
157
158
0
  switch (parser->finish) {
159
0
    case HTTP_FINISH_SAFE_WITH_CB:
160
0
      CALLBACK_MAYBE(parser, on_message_complete);
161
0
      if (err != HPE_OK) return err;
162
163
    /* FALLTHROUGH */
164
0
    case HTTP_FINISH_SAFE:
165
0
      return HPE_OK;
166
0
    case HTTP_FINISH_UNSAFE:
167
0
      parser->reason = "Invalid EOF state";
168
0
      return HPE_INVALID_EOF_STATE;
169
0
    default:
170
0
      abort();
171
0
  }
172
0
}
173
174
175
0
void llhttp_pause(llhttp_t* parser) {
176
0
  if (parser->error != HPE_OK) {
177
0
    return;
178
0
  }
179
180
0
  parser->error = HPE_PAUSED;
181
0
  parser->reason = "Paused";
182
0
}
183
184
185
0
void llhttp_resume(llhttp_t* parser) {
186
0
  if (parser->error != HPE_PAUSED) {
187
0
    return;
188
0
  }
189
190
0
  parser->error = 0;
191
0
}
192
193
194
0
void llhttp_resume_after_upgrade(llhttp_t* parser) {
195
0
  if (parser->error != HPE_PAUSED_UPGRADE) {
196
0
    return;
197
0
  }
198
199
0
  parser->error = 0;
200
0
}
201
202
203
0
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
204
0
  return parser->error;
205
0
}
206
207
208
0
const char* llhttp_get_error_reason(const llhttp_t* parser) {
209
0
  return parser->reason;
210
0
}
211
212
213
0
void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
214
0
  parser->reason = reason;
215
0
}
216
217
218
0
const char* llhttp_get_error_pos(const llhttp_t* parser) {
219
0
  return parser->error_pos;
220
0
}
221
222
223
0
const char* llhttp_errno_name(llhttp_errno_t err) {
224
0
#define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
225
0
  switch (err) {
226
0
    HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
227
0
    default: abort();
228
0
  }
229
0
#undef HTTP_ERRNO_GEN
230
0
}
231
232
233
0
const char* llhttp_method_name(llhttp_method_t method) {
234
0
#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
235
0
  switch (method) {
236
0
    HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
237
0
    default: abort();
238
0
  }
239
0
#undef HTTP_METHOD_GEN
240
0
}
241
242
0
const char* llhttp_status_name(llhttp_status_t status) {
243
0
#define HTTP_STATUS_GEN(NUM, NAME, STRING) case HTTP_STATUS_##NAME: return #STRING;
244
0
  switch (status) {
245
0
    HTTP_STATUS_MAP(HTTP_STATUS_GEN)
246
0
    default: abort();
247
0
  }
248
0
#undef HTTP_STATUS_GEN
249
0
}
250
251
252
0
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
253
0
  if (enabled) {
254
0
    parser->lenient_flags |= LENIENT_HEADERS;
255
0
  } else {
256
0
    parser->lenient_flags &= ~LENIENT_HEADERS;
257
0
  }
258
0
}
259
260
261
0
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
262
0
  if (enabled) {
263
0
    parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
264
0
  } else {
265
0
    parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH;
266
0
  }
267
0
}
268
269
270
0
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
271
0
  if (enabled) {
272
0
    parser->lenient_flags |= LENIENT_KEEP_ALIVE;
273
0
  } else {
274
0
    parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
275
0
  }
276
0
}
277
278
0
void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled) {
279
0
  if (enabled) {
280
0
    parser->lenient_flags |= LENIENT_TRANSFER_ENCODING;
281
0
  } else {
282
0
    parser->lenient_flags &= ~LENIENT_TRANSFER_ENCODING;
283
0
  }
284
0
}
285
286
0
void llhttp_set_lenient_version(llhttp_t* parser, int enabled) {
287
0
  if (enabled) {
288
0
    parser->lenient_flags |= LENIENT_VERSION;
289
0
  } else {
290
0
    parser->lenient_flags &= ~LENIENT_VERSION;
291
0
  }
292
0
}
293
294
0
void llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled) {
295
0
  if (enabled) {
296
0
    parser->lenient_flags |= LENIENT_DATA_AFTER_CLOSE;
297
0
  } else {
298
0
    parser->lenient_flags &= ~LENIENT_DATA_AFTER_CLOSE;
299
0
  }
300
0
}
301
302
0
void llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabled) {
303
0
  if (enabled) {
304
0
    parser->lenient_flags |= LENIENT_OPTIONAL_LF_AFTER_CR;
305
0
  } else {
306
0
    parser->lenient_flags &= ~LENIENT_OPTIONAL_LF_AFTER_CR;
307
0
  }
308
0
}
309
310
0
void llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int enabled) {
311
0
  if (enabled) {
312
0
    parser->lenient_flags |= LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
313
0
  } else {
314
0
    parser->lenient_flags &= ~LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
315
0
  }
316
0
}
317
318
0
void llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enabled) {
319
0
  if (enabled) {
320
0
    parser->lenient_flags |= LENIENT_OPTIONAL_CR_BEFORE_LF;
321
0
  } else {
322
0
    parser->lenient_flags &= ~LENIENT_OPTIONAL_CR_BEFORE_LF;
323
0
  }
324
0
}
325
326
0
void llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int enabled) {
327
0
  if (enabled) {
328
0
    parser->lenient_flags |= LENIENT_SPACES_AFTER_CHUNK_SIZE;
329
0
  } else {
330
0
    parser->lenient_flags &= ~LENIENT_SPACES_AFTER_CHUNK_SIZE;
331
0
  }
332
0
}
333
334
/* Callbacks */
335
336
337
0
int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
338
0
  int err;
339
0
  CALLBACK_MAYBE(s, on_message_begin);
340
0
  return err;
341
0
}
342
343
344
0
int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
345
0
  int err;
346
0
  SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
347
0
  return err;
348
0
}
349
350
351
0
int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
352
0
  int err;
353
0
  CALLBACK_MAYBE(s, on_url_complete);
354
0
  return err;
355
0
}
356
357
358
0
int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
359
0
  int err;
360
0
  SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
361
0
  return err;
362
0
}
363
364
365
0
int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
366
0
  int err;
367
0
  CALLBACK_MAYBE(s, on_status_complete);
368
0
  return err;
369
0
}
370
371
372
0
int llhttp__on_method(llhttp_t* s, const char* p, const char* endp) {
373
0
  int err;
374
0
  SPAN_CALLBACK_MAYBE(s, on_method, p, endp - p);
375
0
  return err;
376
0
}
377
378
379
0
int llhttp__on_method_complete(llhttp_t* s, const char* p, const char* endp) {
380
0
  int err;
381
0
  CALLBACK_MAYBE(s, on_method_complete);
382
0
  return err;
383
0
}
384
385
386
0
int llhttp__on_version(llhttp_t* s, const char* p, const char* endp) {
387
0
  int err;
388
0
  SPAN_CALLBACK_MAYBE(s, on_version, p, endp - p);
389
0
  return err;
390
0
}
391
392
393
0
int llhttp__on_version_complete(llhttp_t* s, const char* p, const char* endp) {
394
0
  int err;
395
0
  CALLBACK_MAYBE(s, on_version_complete);
396
0
  return err;
397
0
}
398
399
400
0
int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
401
0
  int err;
402
0
  SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
403
0
  return err;
404
0
}
405
406
407
0
int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
408
0
  int err;
409
0
  CALLBACK_MAYBE(s, on_header_field_complete);
410
0
  return err;
411
0
}
412
413
414
0
int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
415
0
  int err;
416
0
  SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
417
0
  return err;
418
0
}
419
420
421
0
int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
422
0
  int err;
423
0
  CALLBACK_MAYBE(s, on_header_value_complete);
424
0
  return err;
425
0
}
426
427
428
0
int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
429
0
  int err;
430
0
  CALLBACK_MAYBE(s, on_headers_complete);
431
0
  return err;
432
0
}
433
434
435
0
int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
436
0
  int err;
437
0
  CALLBACK_MAYBE(s, on_message_complete);
438
0
  return err;
439
0
}
440
441
442
0
int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
443
0
  int err;
444
0
  SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
445
0
  return err;
446
0
}
447
448
449
0
int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
450
0
  int err;
451
0
  CALLBACK_MAYBE(s, on_chunk_header);
452
0
  return err;
453
0
}
454
455
456
0
int llhttp__on_chunk_extension_name(llhttp_t* s, const char* p, const char* endp) {
457
0
  int err;
458
0
  SPAN_CALLBACK_MAYBE(s, on_chunk_extension_name, p, endp - p);
459
0
  return err;
460
0
}
461
462
463
0
int llhttp__on_chunk_extension_name_complete(llhttp_t* s, const char* p, const char* endp) {
464
0
  int err;
465
0
  CALLBACK_MAYBE(s, on_chunk_extension_name_complete);
466
0
  return err;
467
0
}
468
469
470
0
int llhttp__on_chunk_extension_value(llhttp_t* s, const char* p, const char* endp) {
471
0
  int err;
472
0
  SPAN_CALLBACK_MAYBE(s, on_chunk_extension_value, p, endp - p);
473
0
  return err;
474
0
}
475
476
477
0
int llhttp__on_chunk_extension_value_complete(llhttp_t* s, const char* p, const char* endp) {
478
0
  int err;
479
0
  CALLBACK_MAYBE(s, on_chunk_extension_value_complete);
480
0
  return err;
481
0
}
482
483
484
0
int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
485
0
  int err;
486
0
  CALLBACK_MAYBE(s, on_chunk_complete);
487
0
  return err;
488
0
}
489
490
491
0
int llhttp__on_reset(llhttp_t* s, const char* p, const char* endp) {
492
0
  int err;
493
0
  CALLBACK_MAYBE(s, on_reset);
494
0
  return err;
495
0
}
496
497
498
/* Private */
499
500
501
void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
502
0
                   const char* msg) {
503
0
  if (p == endp) {
504
0
    fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
505
0
            s->flags, msg);
506
0
  } else {
507
0
    fprintf(stderr, "p=%p type=%d flags=%02x next=%02x   debug=%s\n", s,
508
0
            s->type, s->flags, *p, msg);
509
0
  }
510
0
}