diff --git a/src/expr.cpp b/src/expr.cpp index ecc5e1c0..480a2fd6 100644 --- a/src/expr.cpp +++ b/src/expr.cpp @@ -406,16 +406,28 @@ namespace pkpy{ int count = 0; // how many string parts bool flag = false; // true if we are in a expression + const char* fmt_valid_chars = "0-=*#@!~" "<>^" ".fds" "0123456789"; + PK_LOCAL_STATIC const std::set fmt_valid_char_set(fmt_valid_chars, fmt_valid_chars + strlen(fmt_valid_chars)); + while(j < src.size){ if(flag){ if(src[j] == '}'){ // add expression Str expr = src.substr(i, j-i); + // BUG: ':' is not a format specifier in f"{stack[2:]}" int conon = expr.index(":"); if(conon >= 0){ - _load_simple_expr(ctx, expr.substr(0, conon)); Str spec = expr.substr(conon+1); - ctx->emit_(OP_FORMAT_STRING, ctx->add_const(VAR(spec)), line); + // filter some invalid spec + bool ok = true; + for(char c: spec) if(!fmt_valid_char_set.count(c)){ ok = false; break; } + if(ok){ + _load_simple_expr(ctx, expr.substr(0, conon)); + ctx->emit_(OP_FORMAT_STRING, ctx->add_const(VAR(spec)), line); + }else{ + // ':' is not a spec indicator + _load_simple_expr(ctx, expr); + } }else{ _load_simple_expr(ctx, expr); } diff --git a/tests/04_str.py b/tests/04_str.py index 327b4a9a..b1800ff7 100644 --- a/tests/04_str.py +++ b/tests/04_str.py @@ -153,3 +153,6 @@ a = 'b' assert list(a) == ['b'] a = '测' assert list(a) == ['测'] + +assert '\b\b\b' == '\x08\x08\x08' +stack=[1,2,3,4]; assert f"{stack[2:]}" == '[3, 4]'