From 8c4ed3bc3423f56d907e80ab4dc42dab1267afc3 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 2 Jun 2026 20:42:03 +0800 Subject: [PATCH] fix a bug of `str` --- src/bindings/py_str.c | 3 ++- src/common/str.c | 5 +++-- src/modules/pickle.c | 8 ++++---- tests/041_str.py | 5 +++++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/bindings/py_str.c b/src/bindings/py_str.c index de5c556c..8d8a21ec 100644 --- a/src/bindings/py_str.c +++ b/src/bindings/py_str.c @@ -228,7 +228,8 @@ static bool str__getitem__(int argc, py_Ref argv) { py_Ref _1 = py_arg(1); if(_1->type == tp_int) { int index = py_toint(py_arg(1)); - if(!pk__normalize_index(&index, self.size)) return false; + int u8_len = c11_sv__u8_length(self); + if(!pk__normalize_index(&index, u8_len)) return false; c11_sv res = c11_sv__u8_getitem(self, index); py_newstrv(py_retval(), res); return true; diff --git a/src/common/str.c b/src/common/str.c index 5a336664..6b858d56 100644 --- a/src/common/str.c +++ b/src/common/str.c @@ -104,8 +104,10 @@ c11_sv c11_sv__slice(c11_sv sv, int start) { return c11_sv__slice2(sv, start, sv c11_sv c11_sv__slice2(c11_sv sv, int start, int stop) { if(start < 0) start = 0; - if(stop < start) stop = start; + if(start > sv.size) start = sv.size; + if(stop < 0) stop = 0; if(stop > sv.size) stop = sv.size; + if(stop < start) stop = start; return (c11_sv){sv.data + start, stop - start}; } @@ -997,7 +999,6 @@ const static c11_u32_range kLoRanges[] = { // clang-format on bool c11__is_unicode_Lo_char(int c) { - if(c == 0x1f955) return true; const char* data = c11__search_u32_ranges(c, kLoRanges, sizeof(kLoRanges) / sizeof(c11_u32_range)); return data != NULL; diff --git a/src/modules/pickle.c b/src/modules/pickle.c index 51a7d2fb..2c6c580f 100644 --- a/src/modules/pickle.c +++ b/src/modules/pickle.c @@ -501,10 +501,10 @@ bool py_pickle_loads_body(const unsigned char* p, int memo_length, c11_smallmap_ bool py_pickle_loads(const unsigned char* data, int size) { const unsigned char* p = data; - // \xf0\x9f\xa5\x95 - if(size < 4 || p[0] != 240 || p[1] != 159 || p[2] != 165 || p[3] != 149) + // PK + if(size < 2 || p[0] != 'P' || p[1] != 'K') return ValueError("invalid pickle data"); - p += 4; + p += 2; c11_smallmap_d2d type_mapping; c11_smallmap_d2d__ctor(&type_mapping); @@ -780,7 +780,7 @@ bool py_pickle_loads_body(const unsigned char* p, int memo_length, c11_smallmap_ static bool PickleObject__py_submit(PickleObject* self, py_OutRef out) { c11_sbuf cleartext; c11_sbuf__ctor(&cleartext); - c11_sbuf__write_cstr(&cleartext, "\xf0\x9f\xa5\x95"); + c11_sbuf__write_cstr(&cleartext, "PK"); // line 1: type mapping for(py_Type type = 0; type < self->used_types_length; type++) { if(self->used_types[type]) { diff --git a/tests/041_str.py b/tests/041_str.py index 411990d9..475d15c2 100644 --- a/tests/041_str.py +++ b/tests/041_str.py @@ -221,6 +221,11 @@ assert chr(0x1f955) == '🥕' assert ord('测') == 27979 assert chr(27979) == '测' +assert '测试'[0] == '测' +assert '测试'[1] == '试' +assert '测试'[-1] == '试' +assert '测试'[-2] == '测' + # test format() assert "Hello, {}!".format("World") == "Hello, World!" assert "{} {} {}".format("I", "love", "Python") == "I love Python"