1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * lws System Fault Injection 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_ci#include "private-lib-core.h" 26d4afb5ceSopenharmony_ci 27d4afb5ceSopenharmony_ci#include <assert.h> 28d4afb5ceSopenharmony_ci 29d4afb5ceSopenharmony_cistatic lws_fi_priv_t * 30d4afb5ceSopenharmony_cilws_fi_lookup(const lws_fi_ctx_t *fic, const char *name) 31d4afb5ceSopenharmony_ci{ 32d4afb5ceSopenharmony_ci lws_start_foreach_dll(struct lws_dll2 *, p, fic->fi_owner.head) { 33d4afb5ceSopenharmony_ci lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list); 34d4afb5ceSopenharmony_ci 35d4afb5ceSopenharmony_ci if (!strcmp(pv->fi.name, name)) 36d4afb5ceSopenharmony_ci return pv; 37d4afb5ceSopenharmony_ci 38d4afb5ceSopenharmony_ci } lws_end_foreach_dll(p); 39d4afb5ceSopenharmony_ci 40d4afb5ceSopenharmony_ci return NULL; 41d4afb5ceSopenharmony_ci} 42d4afb5ceSopenharmony_ci 43d4afb5ceSopenharmony_ciint 44d4afb5ceSopenharmony_cilws_fi(const lws_fi_ctx_t *fic, const char *name) 45d4afb5ceSopenharmony_ci{ 46d4afb5ceSopenharmony_ci lws_fi_priv_t *pv; 47d4afb5ceSopenharmony_ci int n; 48d4afb5ceSopenharmony_ci 49d4afb5ceSopenharmony_ci pv = lws_fi_lookup(fic, name); 50d4afb5ceSopenharmony_ci 51d4afb5ceSopenharmony_ci if (!pv) 52d4afb5ceSopenharmony_ci return 0; 53d4afb5ceSopenharmony_ci 54d4afb5ceSopenharmony_ci switch (pv->fi.type) { 55d4afb5ceSopenharmony_ci case LWSFI_ALWAYS: 56d4afb5ceSopenharmony_ci goto inject; 57d4afb5ceSopenharmony_ci 58d4afb5ceSopenharmony_ci case LWSFI_DETERMINISTIC: 59d4afb5ceSopenharmony_ci pv->fi.times++; 60d4afb5ceSopenharmony_ci if (pv->fi.times >= pv->fi.pre) 61d4afb5ceSopenharmony_ci if (pv->fi.times < pv->fi.pre + pv->fi.count) 62d4afb5ceSopenharmony_ci goto inject; 63d4afb5ceSopenharmony_ci return 0; 64d4afb5ceSopenharmony_ci 65d4afb5ceSopenharmony_ci case LWSFI_PROBABILISTIC: 66d4afb5ceSopenharmony_ci if (lws_xos_percent((lws_xos_t *)&fic->xos, (int)pv->fi.pre)) 67d4afb5ceSopenharmony_ci goto inject; 68d4afb5ceSopenharmony_ci return 0; 69d4afb5ceSopenharmony_ci 70d4afb5ceSopenharmony_ci case LWSFI_PATTERN: 71d4afb5ceSopenharmony_ci case LWSFI_PATTERN_ALLOC: 72d4afb5ceSopenharmony_ci n = (int)((pv->fi.times++) % pv->fi.count); 73d4afb5ceSopenharmony_ci if (pv->fi.pattern[n >> 3] & (1 << (n & 7))) 74d4afb5ceSopenharmony_ci goto inject; 75d4afb5ceSopenharmony_ci 76d4afb5ceSopenharmony_ci return 0; 77d4afb5ceSopenharmony_ci 78d4afb5ceSopenharmony_ci default: 79d4afb5ceSopenharmony_ci return 0; 80d4afb5ceSopenharmony_ci } 81d4afb5ceSopenharmony_ci 82d4afb5ceSopenharmony_ci return 0; 83d4afb5ceSopenharmony_ci 84d4afb5ceSopenharmony_ciinject: 85d4afb5ceSopenharmony_ci lwsl_warn("%s: Injecting fault %s->%s\n", __func__, 86d4afb5ceSopenharmony_ci fic->name ? fic->name : "unk", pv->fi.name); 87d4afb5ceSopenharmony_ci 88d4afb5ceSopenharmony_ci return 1; 89d4afb5ceSopenharmony_ci} 90d4afb5ceSopenharmony_ci 91d4afb5ceSopenharmony_ciint 92d4afb5ceSopenharmony_cilws_fi_range(const lws_fi_ctx_t *fic, const char *name, uint64_t *result) 93d4afb5ceSopenharmony_ci{ 94d4afb5ceSopenharmony_ci lws_fi_priv_t *pv; 95d4afb5ceSopenharmony_ci uint64_t d; 96d4afb5ceSopenharmony_ci 97d4afb5ceSopenharmony_ci pv = lws_fi_lookup(fic, name); 98d4afb5ceSopenharmony_ci 99d4afb5ceSopenharmony_ci if (!pv) 100d4afb5ceSopenharmony_ci return 1; 101d4afb5ceSopenharmony_ci 102d4afb5ceSopenharmony_ci if (pv->fi.type != LWSFI_RANGE) { 103d4afb5ceSopenharmony_ci lwsl_err("%s: fault %s is not a 123..456 range\n", 104d4afb5ceSopenharmony_ci __func__, name); 105d4afb5ceSopenharmony_ci return 1; 106d4afb5ceSopenharmony_ci } 107d4afb5ceSopenharmony_ci 108d4afb5ceSopenharmony_ci d = pv->fi.count - pv->fi.pre; 109d4afb5ceSopenharmony_ci 110d4afb5ceSopenharmony_ci *result = pv->fi.pre + (lws_xos((lws_xos_t *)&fic->xos) % d); 111d4afb5ceSopenharmony_ci 112d4afb5ceSopenharmony_ci return 0; 113d4afb5ceSopenharmony_ci} 114d4afb5ceSopenharmony_ci 115d4afb5ceSopenharmony_ciint 116d4afb5ceSopenharmony_ci_lws_fi_user_wsi_fi(struct lws *wsi, const char *name) 117d4afb5ceSopenharmony_ci{ 118d4afb5ceSopenharmony_ci return lws_fi(&wsi->fic, name); 119d4afb5ceSopenharmony_ci} 120d4afb5ceSopenharmony_ci 121d4afb5ceSopenharmony_ciint 122d4afb5ceSopenharmony_ci_lws_fi_user_context_fi(struct lws_context *ctx, const char *name) 123d4afb5ceSopenharmony_ci{ 124d4afb5ceSopenharmony_ci return lws_fi(&ctx->fic, name); 125d4afb5ceSopenharmony_ci} 126d4afb5ceSopenharmony_ci 127d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 128d4afb5ceSopenharmony_ciint 129d4afb5ceSopenharmony_ci_lws_fi_user_ss_fi(struct lws_ss_handle *h, const char *name) 130d4afb5ceSopenharmony_ci{ 131d4afb5ceSopenharmony_ci return lws_fi(&h->fic, name); 132d4afb5ceSopenharmony_ci} 133d4afb5ceSopenharmony_ci 134d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 135d4afb5ceSopenharmony_ciint 136d4afb5ceSopenharmony_ci_lws_fi_user_sspc_fi(struct lws_sspc_handle *h, const char *name) 137d4afb5ceSopenharmony_ci{ 138d4afb5ceSopenharmony_ci return lws_fi(&h->fic, name); 139d4afb5ceSopenharmony_ci} 140d4afb5ceSopenharmony_ci#endif 141d4afb5ceSopenharmony_ci#endif 142d4afb5ceSopenharmony_ci 143d4afb5ceSopenharmony_ciint 144d4afb5ceSopenharmony_cilws_fi_add(lws_fi_ctx_t *fic, const lws_fi_t *fi) 145d4afb5ceSopenharmony_ci{ 146d4afb5ceSopenharmony_ci lws_fi_priv_t *pv; 147d4afb5ceSopenharmony_ci size_t n = strlen(fi->name); 148d4afb5ceSopenharmony_ci 149d4afb5ceSopenharmony_ci pv = lws_malloc(sizeof(*pv) + n + 1, __func__); 150d4afb5ceSopenharmony_ci if (!pv) 151d4afb5ceSopenharmony_ci return 1; 152d4afb5ceSopenharmony_ci 153d4afb5ceSopenharmony_ci lws_dll2_clear(&pv->list); 154d4afb5ceSopenharmony_ci 155d4afb5ceSopenharmony_ci memcpy(&pv->fi, fi, sizeof(*fi)); 156d4afb5ceSopenharmony_ci pv->fi.name = (const char *)&pv[1]; 157d4afb5ceSopenharmony_ci memcpy(&pv[1], fi->name, n + 1); 158d4afb5ceSopenharmony_ci 159d4afb5ceSopenharmony_ci lws_dll2_add_tail(&pv->list, &fic->fi_owner); 160d4afb5ceSopenharmony_ci 161d4afb5ceSopenharmony_ci return 0; 162d4afb5ceSopenharmony_ci} 163d4afb5ceSopenharmony_ci 164d4afb5ceSopenharmony_civoid 165d4afb5ceSopenharmony_cilws_fi_remove(lws_fi_ctx_t *fic, const char *name) 166d4afb5ceSopenharmony_ci{ 167d4afb5ceSopenharmony_ci lws_fi_priv_t *pv = lws_fi_lookup(fic, name); 168d4afb5ceSopenharmony_ci 169d4afb5ceSopenharmony_ci if (!pv) 170d4afb5ceSopenharmony_ci return; 171d4afb5ceSopenharmony_ci 172d4afb5ceSopenharmony_ci lws_dll2_remove(&pv->list); 173d4afb5ceSopenharmony_ci lws_free(pv); 174d4afb5ceSopenharmony_ci} 175d4afb5ceSopenharmony_ci 176d4afb5ceSopenharmony_civoid 177d4afb5ceSopenharmony_cilws_fi_import(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src) 178d4afb5ceSopenharmony_ci{ 179d4afb5ceSopenharmony_ci 180d4afb5ceSopenharmony_ci /* inherit the PRNG seed for our context from source guy too */ 181d4afb5ceSopenharmony_ci lws_xos_init(&fic_dest->xos, lws_xos((lws_xos_t *)&fic_src->xos)); 182d4afb5ceSopenharmony_ci 183d4afb5ceSopenharmony_ci lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1, 184d4afb5ceSopenharmony_ci fic_src->fi_owner.head) { 185d4afb5ceSopenharmony_ci lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list); 186d4afb5ceSopenharmony_ci 187d4afb5ceSopenharmony_ci lws_dll2_remove(&pv->list); 188d4afb5ceSopenharmony_ci lws_dll2_add_tail(&pv->list, &fic_dest->fi_owner); 189d4afb5ceSopenharmony_ci 190d4afb5ceSopenharmony_ci } lws_end_foreach_dll_safe(p, p1); 191d4afb5ceSopenharmony_ci} 192d4afb5ceSopenharmony_ci 193d4afb5ceSopenharmony_cistatic void 194d4afb5ceSopenharmony_cido_inherit(lws_fi_ctx_t *fic_dest, lws_fi_t *pfi, size_t trim) 195d4afb5ceSopenharmony_ci{ 196d4afb5ceSopenharmony_ci lws_fi_t fi = *pfi; 197d4afb5ceSopenharmony_ci 198d4afb5ceSopenharmony_ci fi.name += trim; 199d4afb5ceSopenharmony_ci 200d4afb5ceSopenharmony_ci lwsl_info("%s: %s: %s inherited as %s\n", __func__, fic_dest->name, 201d4afb5ceSopenharmony_ci pfi->name, fi.name); 202d4afb5ceSopenharmony_ci 203d4afb5ceSopenharmony_ci if (fi.type == LWSFI_PATTERN_ALLOC) { 204d4afb5ceSopenharmony_ci fi.pattern = lws_malloc((size_t)((fi.count >> 3) + 1), __func__); 205d4afb5ceSopenharmony_ci if (!fi.pattern) 206d4afb5ceSopenharmony_ci return; 207d4afb5ceSopenharmony_ci memcpy((uint8_t *)fi.pattern, pfi->pattern, 208d4afb5ceSopenharmony_ci (size_t)((fi.count >> 3) + 1)); 209d4afb5ceSopenharmony_ci } 210d4afb5ceSopenharmony_ci 211d4afb5ceSopenharmony_ci lws_fi_add(fic_dest, &fi); 212d4afb5ceSopenharmony_ci} 213d4afb5ceSopenharmony_ci 214d4afb5ceSopenharmony_civoid 215d4afb5ceSopenharmony_cilws_fi_inherit_copy(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src, 216d4afb5ceSopenharmony_ci const char *scope, const char *value) 217d4afb5ceSopenharmony_ci{ 218d4afb5ceSopenharmony_ci size_t sl = 0, vl = 0; 219d4afb5ceSopenharmony_ci 220d4afb5ceSopenharmony_ci if (scope) 221d4afb5ceSopenharmony_ci sl = strlen(scope); 222d4afb5ceSopenharmony_ci 223d4afb5ceSopenharmony_ci if (value) 224d4afb5ceSopenharmony_ci vl = strlen(value); 225d4afb5ceSopenharmony_ci 226d4afb5ceSopenharmony_ci lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1, 227d4afb5ceSopenharmony_ci fic_src->fi_owner.head) { 228d4afb5ceSopenharmony_ci lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list); 229d4afb5ceSopenharmony_ci size_t nl = strlen(pv->fi.name); 230d4afb5ceSopenharmony_ci 231d4afb5ceSopenharmony_ci if (!scope) 232d4afb5ceSopenharmony_ci do_inherit(fic_dest, &pv->fi, 0); 233d4afb5ceSopenharmony_ci else 234d4afb5ceSopenharmony_ci if (nl > sl + 2 && 235d4afb5ceSopenharmony_ci !strncmp(pv->fi.name, scope, sl) && 236d4afb5ceSopenharmony_ci pv->fi.name[sl] == '/') 237d4afb5ceSopenharmony_ci do_inherit(fic_dest, &pv->fi, sl + 1); 238d4afb5ceSopenharmony_ci else { 239d4afb5ceSopenharmony_ci if (value && nl > sl + vl + 2 && 240d4afb5ceSopenharmony_ci pv->fi.name[sl] == '=' && 241d4afb5ceSopenharmony_ci !strncmp(pv->fi.name + sl + 1, value, vl) && 242d4afb5ceSopenharmony_ci pv->fi.name[sl + 1 + vl] == '/') 243d4afb5ceSopenharmony_ci do_inherit(fic_dest, &pv->fi, sl + vl + 2); 244d4afb5ceSopenharmony_ci } 245d4afb5ceSopenharmony_ci 246d4afb5ceSopenharmony_ci } lws_end_foreach_dll_safe(p, p1); 247d4afb5ceSopenharmony_ci} 248d4afb5ceSopenharmony_ci 249d4afb5ceSopenharmony_civoid 250d4afb5ceSopenharmony_cilws_fi_destroy(const lws_fi_ctx_t *fic) 251d4afb5ceSopenharmony_ci{ 252d4afb5ceSopenharmony_ci lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1, 253d4afb5ceSopenharmony_ci fic->fi_owner.head) { 254d4afb5ceSopenharmony_ci lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list); 255d4afb5ceSopenharmony_ci 256d4afb5ceSopenharmony_ci if (pv->fi.type == LWSFI_PATTERN_ALLOC && pv->fi.pattern) { 257d4afb5ceSopenharmony_ci lws_free((void *)pv->fi.pattern); 258d4afb5ceSopenharmony_ci pv->fi.pattern = NULL; 259d4afb5ceSopenharmony_ci } 260d4afb5ceSopenharmony_ci 261d4afb5ceSopenharmony_ci lws_dll2_remove(&pv->list); 262d4afb5ceSopenharmony_ci lws_free(pv); 263d4afb5ceSopenharmony_ci 264d4afb5ceSopenharmony_ci } lws_end_foreach_dll_safe(p, p1); 265d4afb5ceSopenharmony_ci} 266d4afb5ceSopenharmony_ci 267d4afb5ceSopenharmony_ci/* 268d4afb5ceSopenharmony_ci * We want to support these kinds of qualifier 269d4afb5ceSopenharmony_ci * 270d4afb5ceSopenharmony_ci * myfault true always 271d4afb5ceSopenharmony_ci * myfault(10%) true 10% of the time 272d4afb5ceSopenharmony_ci * myfault(....X X) true when X 273d4afb5ceSopenharmony_ci * myfault2(20..3000) pick a number between 20 and 3000 274d4afb5ceSopenharmony_ci */ 275d4afb5ceSopenharmony_ci 276d4afb5ceSopenharmony_cienum { 277d4afb5ceSopenharmony_ci PARSE_NAME, 278d4afb5ceSopenharmony_ci PARSE_WHEN, 279d4afb5ceSopenharmony_ci PARSE_PC, 280d4afb5ceSopenharmony_ci PARSE_ENDBR, 281d4afb5ceSopenharmony_ci PARSE_COMMA 282d4afb5ceSopenharmony_ci}; 283d4afb5ceSopenharmony_ci 284d4afb5ceSopenharmony_civoid 285d4afb5ceSopenharmony_cilws_fi_deserialize(lws_fi_ctx_t *fic, const char *sers) 286d4afb5ceSopenharmony_ci{ 287d4afb5ceSopenharmony_ci int state = PARSE_NAME, m; 288d4afb5ceSopenharmony_ci struct lws_tokenize ts; 289d4afb5ceSopenharmony_ci lws_fi_t fi; 290d4afb5ceSopenharmony_ci char nm[64]; 291d4afb5ceSopenharmony_ci 292d4afb5ceSopenharmony_ci /* 293d4afb5ceSopenharmony_ci * Go through the comma-separated list of faults 294d4afb5ceSopenharmony_ci * creating them and adding to the lws_context info 295d4afb5ceSopenharmony_ci */ 296d4afb5ceSopenharmony_ci 297d4afb5ceSopenharmony_ci lws_tokenize_init(&ts, sers, LWS_TOKENIZE_F_DOT_NONTERM | 298d4afb5ceSopenharmony_ci LWS_TOKENIZE_F_NO_INTEGERS | 299d4afb5ceSopenharmony_ci LWS_TOKENIZE_F_NO_FLOATS | 300d4afb5ceSopenharmony_ci LWS_TOKENIZE_F_EQUALS_NONTERM | 301d4afb5ceSopenharmony_ci LWS_TOKENIZE_F_SLASH_NONTERM | 302d4afb5ceSopenharmony_ci LWS_TOKENIZE_F_MINUS_NONTERM); 303d4afb5ceSopenharmony_ci ts.len = (unsigned int)strlen(sers); 304d4afb5ceSopenharmony_ci if (ts.len < 1 || ts.len > 10240) 305d4afb5ceSopenharmony_ci return; 306d4afb5ceSopenharmony_ci 307d4afb5ceSopenharmony_ci do { 308d4afb5ceSopenharmony_ci ts.e = (int8_t)lws_tokenize(&ts); 309d4afb5ceSopenharmony_ci switch (ts.e) { 310d4afb5ceSopenharmony_ci case LWS_TOKZE_TOKEN: 311d4afb5ceSopenharmony_ci 312d4afb5ceSopenharmony_ci if (state == PARSE_NAME) { 313d4afb5ceSopenharmony_ci /* 314d4afb5ceSopenharmony_ci * One fault to inject looks like, eg, 315d4afb5ceSopenharmony_ci * 316d4afb5ceSopenharmony_ci * vh=xxx/listenskt 317d4afb5ceSopenharmony_ci */ 318d4afb5ceSopenharmony_ci 319d4afb5ceSopenharmony_ci memset(&fi, 0, sizeof(fi)); 320d4afb5ceSopenharmony_ci 321d4afb5ceSopenharmony_ci lws_strnncpy(nm, ts.token, ts.token_len, 322d4afb5ceSopenharmony_ci sizeof(nm)); 323d4afb5ceSopenharmony_ci fi.name = nm; 324d4afb5ceSopenharmony_ci fi.type = LWSFI_ALWAYS; 325d4afb5ceSopenharmony_ci 326d4afb5ceSopenharmony_ci lwsl_notice("%s: name %.*s\n", __func__, 327d4afb5ceSopenharmony_ci (int)ts.token_len, ts.token); 328d4afb5ceSopenharmony_ci 329d4afb5ceSopenharmony_ci /* added later, potentially after (when) */ 330d4afb5ceSopenharmony_ci break; 331d4afb5ceSopenharmony_ci } 332d4afb5ceSopenharmony_ci if (state == PARSE_WHEN) { 333d4afb5ceSopenharmony_ci /* it's either numeric (then % or ..num2), or 334d4afb5ceSopenharmony_ci * .X pattern */ 335d4afb5ceSopenharmony_ci 336d4afb5ceSopenharmony_ci lwsl_notice("%s: when\n", __func__); 337d4afb5ceSopenharmony_ci 338d4afb5ceSopenharmony_ci if (*ts.token == '.' || *ts.token == 'X') { 339d4afb5ceSopenharmony_ci uint8_t *pat; 340d4afb5ceSopenharmony_ci size_t n; 341d4afb5ceSopenharmony_ci 342d4afb5ceSopenharmony_ci /* 343d4afb5ceSopenharmony_ci * pattern... we need to allocate it 344d4afb5ceSopenharmony_ci */ 345d4afb5ceSopenharmony_ci fi.type = LWSFI_PATTERN_ALLOC; 346d4afb5ceSopenharmony_ci pat = lws_zalloc((ts.token_len >> 3) + 1, 347d4afb5ceSopenharmony_ci __func__); 348d4afb5ceSopenharmony_ci if (!pat) 349d4afb5ceSopenharmony_ci return; 350d4afb5ceSopenharmony_ci fi.pattern = pat; 351d4afb5ceSopenharmony_ci fi.count = (uint64_t)ts.token_len; 352d4afb5ceSopenharmony_ci 353d4afb5ceSopenharmony_ci for (n = 0; n < ts.token_len; n++) 354d4afb5ceSopenharmony_ci if (ts.token[n] == 'X') 355d4afb5ceSopenharmony_ci pat[n >> 3] = (uint8_t)( 356d4afb5ceSopenharmony_ci pat[n >> 3] | 357d4afb5ceSopenharmony_ci (1 << (n & 7))); 358d4afb5ceSopenharmony_ci 359d4afb5ceSopenharmony_ci lwsl_hexdump_notice(pat, 360d4afb5ceSopenharmony_ci (ts.token_len >> 3) + 1); 361d4afb5ceSopenharmony_ci 362d4afb5ceSopenharmony_ci state = PARSE_ENDBR; 363d4afb5ceSopenharmony_ci break; 364d4afb5ceSopenharmony_ci } 365d4afb5ceSopenharmony_ci 366d4afb5ceSopenharmony_ci fi.pre = (uint64_t)atoll(ts.token); 367d4afb5ceSopenharmony_ci 368d4afb5ceSopenharmony_ci for (m = 0; m < (int)ts.token_len - 1; m++) 369d4afb5ceSopenharmony_ci if (ts.token[m] < '0' || 370d4afb5ceSopenharmony_ci ts.token[m] > '9') 371d4afb5ceSopenharmony_ci break; 372d4afb5ceSopenharmony_ci 373d4afb5ceSopenharmony_ci /* 374d4afb5ceSopenharmony_ci * We can understand num% or num..num 375d4afb5ceSopenharmony_ci */ 376d4afb5ceSopenharmony_ci 377d4afb5ceSopenharmony_ci if (m != (int)ts.token_len && 378d4afb5ceSopenharmony_ci ts.token[m] == '.' && 379d4afb5ceSopenharmony_ci ts.token[m + 1] == '.') { 380d4afb5ceSopenharmony_ci fi.count = (uint64_t)atoll( 381d4afb5ceSopenharmony_ci &ts.token[m + 2]); 382d4afb5ceSopenharmony_ci fi.type = LWSFI_RANGE; 383d4afb5ceSopenharmony_ci state = PARSE_ENDBR; 384d4afb5ceSopenharmony_ci 385d4afb5ceSopenharmony_ci if (fi.pre >= fi.count) { 386d4afb5ceSopenharmony_ci lwsl_err("%s: range must have " 387d4afb5ceSopenharmony_ci "smaller first!\n", 388d4afb5ceSopenharmony_ci __func__); 389d4afb5ceSopenharmony_ci } 390d4afb5ceSopenharmony_ci 391d4afb5ceSopenharmony_ci lwsl_notice("%s: range %llx .." 392d4afb5ceSopenharmony_ci "%llx\n", __func__, 393d4afb5ceSopenharmony_ci (unsigned long long)fi.pre, 394d4afb5ceSopenharmony_ci (unsigned long long)fi.count); 395d4afb5ceSopenharmony_ci break; 396d4afb5ceSopenharmony_ci } 397d4afb5ceSopenharmony_ci 398d4afb5ceSopenharmony_ci lwsl_notice("%s: prob %d%%\n", __func__, 399d4afb5ceSopenharmony_ci (int)fi.pre); 400d4afb5ceSopenharmony_ci fi.type = LWSFI_PROBABILISTIC; 401d4afb5ceSopenharmony_ci state = PARSE_PC; 402d4afb5ceSopenharmony_ci break; 403d4afb5ceSopenharmony_ci } 404d4afb5ceSopenharmony_ci break; 405d4afb5ceSopenharmony_ci 406d4afb5ceSopenharmony_ci case LWS_TOKZE_DELIMITER: 407d4afb5ceSopenharmony_ci if (*ts.token == ',') { 408d4afb5ceSopenharmony_ci lws_fi_add(fic, &fi); 409d4afb5ceSopenharmony_ci state = PARSE_NAME; 410d4afb5ceSopenharmony_ci break; 411d4afb5ceSopenharmony_ci } 412d4afb5ceSopenharmony_ci if (*ts.token == '(') { 413d4afb5ceSopenharmony_ci lwsl_notice("%s: (\n", __func__); 414d4afb5ceSopenharmony_ci if (state != PARSE_NAME) { 415d4afb5ceSopenharmony_ci lwsl_err("%s: misplaced (\n", __func__); 416d4afb5ceSopenharmony_ci return; 417d4afb5ceSopenharmony_ci } 418d4afb5ceSopenharmony_ci state = PARSE_WHEN; 419d4afb5ceSopenharmony_ci break; 420d4afb5ceSopenharmony_ci } 421d4afb5ceSopenharmony_ci if (*ts.token == ')') { 422d4afb5ceSopenharmony_ci if (state != PARSE_ENDBR) { 423d4afb5ceSopenharmony_ci lwsl_err("%s: misplaced )\n", __func__); 424d4afb5ceSopenharmony_ci return; 425d4afb5ceSopenharmony_ci } 426d4afb5ceSopenharmony_ci state = PARSE_NAME; 427d4afb5ceSopenharmony_ci break; 428d4afb5ceSopenharmony_ci } 429d4afb5ceSopenharmony_ci if (*ts.token == '%') { 430d4afb5ceSopenharmony_ci if (state != PARSE_PC) { 431d4afb5ceSopenharmony_ci lwsl_err("%s: misplaced %%\n", __func__); 432d4afb5ceSopenharmony_ci return; 433d4afb5ceSopenharmony_ci } 434d4afb5ceSopenharmony_ci state = PARSE_ENDBR; 435d4afb5ceSopenharmony_ci break; 436d4afb5ceSopenharmony_ci } 437d4afb5ceSopenharmony_ci break; 438d4afb5ceSopenharmony_ci 439d4afb5ceSopenharmony_ci case LWS_TOKZE_ENDED: 440d4afb5ceSopenharmony_ci lws_fi_add(fic, &fi); 441d4afb5ceSopenharmony_ci return; 442d4afb5ceSopenharmony_ci 443d4afb5ceSopenharmony_ci default: 444d4afb5ceSopenharmony_ci return; 445d4afb5ceSopenharmony_ci } 446d4afb5ceSopenharmony_ci } while (ts.e > 0); 447d4afb5ceSopenharmony_ci} 448