Repository navigation
Commit c07f175
fix(addressparser): parse comment-joined addresses in linear time
The join check read the accumulator's last character back with
parts[parts.length - 1].slice(-1). That flattens the whole growing run on
every token, so an address built from many comment-joined atoms, such as
'a@b(c)@b(c)...', parsed in O(n^2): 1.5MB of address blocked the event
loop for about 10 seconds.
The run only ever grows by the token appended in that same branch, so its
last character is now carried alongside it per state rather than re-read
off the accumulator. Parse output is unchanged, verified by a 80k input
differential fuzz against the previous implementation.
Reachable without authentication anywhere inbound headers are parsed with
this module, mailparser being the notable case. Reordering the operands so
the cheap token.value.charAt(0) test runs first was not enough: it only
short-circuits when the atom after the comment starts with '@', and
'a@(c)b@(c)b@...' stays quadratic. Both shapes are covered by tests.
Fixes GHSA-prgh-xp8r-p3m5
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01QWP5uaVCxv26wEFF3uE1J11 parent ad54add commit c07f175
2 files changed
Lines changed: 41 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
58 | 63 | | |
59 | 64 | | |
60 | 65 | | |
| |||
193 | 198 | | |
194 | 199 | | |
195 | 200 | | |
196 | | - | |
| 201 | + | |
197 | 202 | | |
198 | 203 | | |
199 | 204 | | |
| |||
203 | 208 | | |
204 | 209 | | |
205 | 210 | | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
206 | 217 | | |
207 | 218 | | |
208 | 219 | | |
| |||
248 | 259 | | |
249 | 260 | | |
250 | 261 | | |
251 | | - | |
| 262 | + | |
252 | 263 | | |
253 | 264 | | |
254 | 265 | | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
255 | 269 | | |
256 | 270 | | |
257 | 271 | | |
258 | 272 | | |
259 | 273 | | |
| 274 | + | |
260 | 275 | | |
261 | 276 | | |
262 | 277 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1179 | 1179 | | |
1180 | 1180 | | |
1181 | 1181 | | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
| 1203 | + | |
| 1204 | + | |
| 1205 | + | |
1182 | 1206 | | |
1183 | 1207 | | |
1184 | 1208 | | |
| |||
0 commit comments