Skip to content

Commit

Permalink
BUG/MINOR: h1: fix detection of upper bytes in the URI
Browse files Browse the repository at this point in the history
In 1.7 with commit 5f10ea3 ("OPTIM: http: improve parsing performance
of long URIs") we improved the URI parser's performance on platforms
supporting unaligned accesses by reading 4 chars at a time in a 32-bit
word. However, as reported in GH issue #2545, there's a bug in the way
the top bytes are checked, as the parser will stop when all 4 of them
are above 7e instead of when one of them is, so certain patterns can be
accepted through if the last ones are all valid. The fix requires to
negate the value but on the other hand it allows to parallelize some of
the tests and fuse the masks, which could even end up slightly faster.

This needs to be backported to all stable versions, but be careful, this
code moved a lot over time, from proto_http.c to h1.c, to http_msg.c, to
h1.c again. Better just grep for "24242424" or "21212121" in each version
to find it.

Big kudos to Martijn van Oosterhout (@kleptog) for spotting this problem
while analyzing that piece of code, and reporting it.
  • Loading branch information
wtarreau committed Apr 24, 2024
1 parent 98d22f2 commit b9bf16b
Showing 1 changed file with 2 additions and 5 deletions.
7 changes: 2 additions & 5 deletions src/h1.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,9 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
#ifdef HA_UNALIGNED_LE
/* speedup: skip bytes not between 0x24 and 0x7e inclusive */
while (ptr <= end - sizeof(int)) {
int x = *(int *)ptr - 0x24242424;
if (x & 0x80808080)
break;
uint x = *(uint *)ptr;

x -= 0x5b5b5b5b;
if (!(x & 0x80808080))
if (((x - 0x24242424) | (0x7e7e7e7e - x)) & 0x80808080U)
break;

ptr += sizeof(int);
Expand Down

0 comments on commit b9bf16b

Please sign in to comment.