@@ -3467,7 +3467,7 @@ typedef struct fio_buf_info_s {
34673467/** Creates a stack fio_str_info_s variable `name` with `capacity` bytes. */
34683468#define FIO_STR_INFO_TMP_VAR(name, capacity) \
34693469 char fio___stack_mem___##name[(capacity) + 1]; \
3470- fio___stack_mem___##name[(capacity) ] = 0; /* guard */ \
3470+ fio___stack_mem___##name[0 ] = 0; /* guard */ \
34713471 fio_str_info_s name = (fio_str_info_s) { \
34723472 .buf = fio___stack_mem___##name, .capa = (capacity) \
34733473 }
@@ -3761,17 +3761,22 @@ FIO_BASIC Basic Kitchen Sink Inclusion
37613761FIO_CRYPT Poor-man's Cryptographic Elements
37623762***************************************************************************** */
37633763#if defined(FIO_CRYPT)
3764+ #undef FIO_CRYPT
3765+ #undef FIO_CRYPTO_CORE
37643766#undef FIO_CHACHA
37653767#undef FIO_ED25519
37663768#undef FIO_SHA1
37673769#undef FIO_SHA2
3770+ #undef FIO_SECRET
3771+ #undef FIO_OTP
37683772#define FIO_CRYPTO_CORE
37693773#define FIO_CHACHA
37703774#define FIO_ED25519
37713775#define FIO_SHA1
37723776#define FIO_SHA2
37733777#define FIO_SECRET
3774- #undef FIO_CRYPT
3778+ #define FIO_OTP
3779+
37753780#endif /* FIO_CRYPT */
37763781
37773782/* *****************************************************************************
@@ -24342,7 +24347,7 @@ typedef struct {
2434224347 size_t interval; /* 30 == Google OTP */
2434324348 /** The number of digits in the OTP. */
2434424349 size_t digits; /* 6 == Google OTP */
24345- /** The time offset (in seconds ) from the current time. */
24350+ /** The time offset (in `interval` units ) from the current time. */
2434624351 int64_t offset; /* 0 == Google OTP */
2434724352 /** Set to true if the secret / key is in Hex instead of Byte32 encoding. */
2434824353 uint8_t is_hex;
@@ -24410,7 +24415,7 @@ SFUNC uint32_t fio_otp FIO_NOOP(fio_buf_info_s key,
2441024415 fio___otp_settings_validate(&settings);
2441124416
2441224417 /* Prep time */
24413- t -= settings.offset;
24418+ t -= ( settings.offset * settings.interval) ;
2441424419 t /= settings.interval;
2441524420 /* t should be big endian */
2441624421 t = fio_lton64(t);
@@ -43353,6 +43358,38 @@ size_t fio_http_response_header_each(
4335343358Cookies
4335443359***************************************************************************** */
4335543360
43361+ FIO_IFUNC void fio___http_cookie_set_if_missing_encoded(fio_http_s *h,
43362+ fio_str_info_s k,
43363+ fio_str_info_s v) {
43364+ char *div = NULL;
43365+ FIO_STR_INFO_TMP_VAR(dec, 8192);
43366+ /* TODO: test for percent encoding... */
43367+ if ((div = (char *)FIO_MEMCHR(k.buf, '%', k.len))) {
43368+ if (div + 2 < (k.buf + k.len) && fio_c2i(div[1]) < 16 &&
43369+ fio_c2i(div[2]) < 16 &&
43370+ !fio_string_write_path_dec(&dec, FIO_STRING_ALLOC_COPY, k.buf, k.len))
43371+ k = dec;
43372+ }
43373+ if ((div = (char *)FIO_MEMCHR(v.buf, '%', v.len))) {
43374+ fio_str_info_s old = dec;
43375+ if (div + 2 < (v.buf + v.len) && fio_c2i(div[1]) < 16 &&
43376+ fio_c2i(div[2]) < 16 &&
43377+ !fio_string_write_path_dec(&dec,
43378+ FIO_STR_INFO_TMP_IS_REALLOCATED(dec)
43379+ ? FIO_STRING_REALLOC
43380+ : FIO_STRING_ALLOC_COPY,
43381+ v.buf,
43382+ v.len)) {
43383+ v = dec;
43384+ v.buf += old.len;
43385+ v.len -= old.len;
43386+ }
43387+ }
43388+ fio___http_cmap_set_if_missing(h->cookies, k, v);
43389+ if (FIO_STR_INFO_TMP_IS_REALLOCATED(dec))
43390+ FIO_STRING_FREE2(dec);
43391+ }
43392+
4335643393/** (Helper) HTTP Cookie Parser */
4335743394FIO_IFUNC void fio___http_cookie_parse_cookie(fio_http_s *h, fio_str_info_s s) {
4335843395 /* loop and read Cookie: name=value; name2=value2; name3=value3 */
@@ -43382,7 +43419,7 @@ FIO_IFUNC void fio___http_cookie_parse_cookie(fio_http_s *h, fio_str_info_s s) {
4338243419 /* skip the ';' if exists (if len is not zero, !!s.len == 1). */
4338343420 s.buf += !!s.len;
4338443421 s.len -= !!s.len;
43385- fio___http_cmap_set_if_missing(h->cookies , k, v);
43422+ fio___http_cookie_set_if_missing_encoded(h , k, v);
4338643423 }
4338743424}
4338843425
@@ -43427,7 +43464,7 @@ FIO_IFUNC void fio___http_cookie_parse_set_cookie(fio_http_s *h,
4342743464 }
4342843465 } while (cont);
4342943466 if (k.len)
43430- fio___http_cmap_set_if_missing(h->cookies , k, v);
43467+ fio___http_cookie_set_if_missing_encoded(h , k, v);
4343143468}
4343243469
4343343470/** (Helper) Parses all HTTP Cookies */
@@ -43473,9 +43510,12 @@ SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
4347343510 ('A'.ord..'Z'.ord).each {|i| a[i] = 0;}
4347443511 ('0'.ord..'9'.ord).each {|i| a[i] = 0;}
4347543512 "!#$%&'*+-.^_`|~".bytes.each {|i| a[i] = 0;}
43476- p a; nil
43513+ puts "static const char invalid_cookie_name_char[256] = {"
43514+ puts "#{ a.map {|i| i.to_s } .join(', ') }};"
4347743515 "!#$%&'()*+-./:<=>?@[]^_`{|}~".bytes.each {|i| a[i] = 0;} # for values
43478- p a; nil
43516+ ",\"\\".bytes.each {|i| a[i] = 0;} # commonly used, though not allowed
43517+ puts "static const char invalid_cookie_value_char[256] = {"
43518+ puts "#{ a.map {|i| i.to_s } .join(', ') }};"
4347943519 */
4348043520 static const char invalid_cookie_name_char[256] = {
4348143521 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -43491,9 +43531,9 @@ SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
4349143531 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
4349243532 static const char invalid_cookie_value_char[256] = {
4349343533 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
43494- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 , 0, 0, 0,
43534+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0,
4349543535 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43496- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 , 0, 0, 0,
43536+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0,
4349743537 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4349843538 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4349943539 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -43510,20 +43550,20 @@ SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
4351043550 fio_str_info_s t = FIO_STR_INFO3(tmp_buf, 0, 5119);
4351143551
4351243552#define fio___http_h_copy_cookie_ch(ch_var) \
43553+ if (t.capa <= t.len + 3) { \
43554+ ((t.buf == tmp_buf) \
43555+ ? FIO_STRING_ALLOC_COPY \
43556+ : FIO_STRING_REALLOC)(&t, fio_string_capa4len(t.len + 3)); \
43557+ } \
4351343558 if (!invalid_cookie_##ch_var##_char[(uint8_t)cookie.ch_var.buf[tmp]]) { \
4351443559 t.buf[t.len++] = cookie.ch_var.buf[tmp]; \
4351543560 } else { \
43516- need2warn |= 1; \
43561+ need2warn = tmp + 1; \
4351743562 t.buf[t.len++] = '%'; \
4351843563 t.buf[t.len++] = fio_i2c(((uint8_t)cookie.ch_var.buf[tmp] >> 4) & 0x0F); \
4351943564 t.buf[t.len++] = fio_i2c((uint8_t)cookie.ch_var.buf[tmp] & 0x0F); \
4352043565 } \
43521- tmp += 1; \
43522- if (t.capa <= t.len + 3) { \
43523- ((t.buf == tmp_buf) \
43524- ? FIO_STRING_ALLOC_COPY \
43525- : FIO_STRING_REALLOC)(&t, fio_string_capa4len(t.len + 3)); \
43526- }
43566+ tmp += 1;
4352743567
4352843568 if (cookie.name.buf) {
4352943569 size_t tmp = 0;
@@ -43540,7 +43580,7 @@ SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
4354043580 warn_illegal |= 1;
4354143581 FIO_LOG_WARNING("illegal char 0x%.2x in cookie name (in %s)\n"
4354243582 " automatic %% encoding applied",
43543- cookie.name.buf[tmp ],
43583+ cookie.name.buf[need2warn - 1 ],
4354443584 cookie.name.buf);
4354543585 }
4354643586 }
@@ -43560,7 +43600,7 @@ SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
4356043600 warn_illegal |= 1;
4356143601 FIO_LOG_WARNING("illegal char 0x%.2x in cookie value (in %s)\n"
4356243602 " automatic %% encoding applied",
43563- cookie.value.buf[tmp ],
43603+ cookie.value.buf[need2warn - 1 ],
4356443604 cookie.value.buf);
4356543605 }
4356643606 } else
0 commit comments