Skip to content

Commit 4d90923

Browse files
committed
http: cast input to unsigned char in ragel parsers
The HTTP ragel state machines in src/http/{chunk_parsers,request_parser, response_parser}.rl declare obs_text = 0x80..0xFF per RFC 7230 §3.2.6, but the generated code compares (*p) directly where p is const char*. On platforms whose ABI defines `char` as signed (x86_64) the 0x80..0xFF range comparisons happen to land bytes on the obs_text state by way of how negative chars sort against the literal byte values; on platforms where `char` is unsigned (aarch64) the same bytes route through a "byte > 122" path and the parser rejects valid input. Add `getkey ((unsigned char)(*p));` to each machine so ragel emits an explicit unsigned-char cast in every comparison. The fix is local to the three .rl files; no compiler flag or input-buffer type change is required. This affects both seastar's HTTP server (http_request_parser via include/seastar/http/httpd.hh) and its HTTP client (http_response_parser via src/http/client.cc), so the bug surfaces on any seastar-based service running on arm64 that receives or sends obs_text in field values. Fixes scylladb#3413.
1 parent 21e446f commit 4d90923

3 files changed

Lines changed: 16 additions & 0 deletions

File tree

src/http/chunk_parsers.rl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ namespace seastar {
3232
%%{
3333

3434
access _fsm_;
35+
# Treat the input as unsigned so the obs_text (0x80..0xff) range is
36+
# accepted on platforms where `char` defaults to signed (x86_64) and
37+
# unsigned (aarch64) alike. See scylladb/seastar issue #3413.
38+
getkey ((unsigned char)(*p));
3539

3640
action mark {
3741
g.mark_start(p);
@@ -152,6 +156,10 @@ public:
152156
%%{
153157

154158
access _fsm_;
159+
# Treat the input as unsigned so the obs_text (0x80..0xff) range is
160+
# accepted on platforms where `char` defaults to signed (x86_64) and
161+
# unsigned (aarch64) alike. See scylladb/seastar issue #3413.
162+
getkey ((unsigned char)(*p));
155163

156164
action mark {
157165
g.mark_start(p);

src/http/request_parser.rl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ namespace seastar {
3333
%%{
3434

3535
access _fsm_;
36+
# Treat the input as unsigned so the obs_text (0x80..0xff) range is
37+
# accepted on platforms where `char` defaults to signed (x86_64) and
38+
# unsigned (aarch64) alike. See scylladb/seastar issue #3413.
39+
getkey ((unsigned char)(*p));
3640

3741
action mark {
3842
g.mark_start(p);

src/http/response_parser.rl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ namespace seastar {
3535
%%{
3636

3737
access _fsm_;
38+
# Treat the input as unsigned so the obs_text (0x80..0xff) range is
39+
# accepted on platforms where `char` defaults to signed (x86_64) and
40+
# unsigned (aarch64) alike. See scylladb/seastar issue #3413.
41+
getkey ((unsigned char)(*p));
3842

3943
action mark {
4044
g.mark_start(p);

0 commit comments

Comments
 (0)