Commit c15d801
committed
fix(sqs): gate v2 receipt handles at the public API boundary
CodeRabbit major on PR #724 round 2: the v2 codec is in the
binary AND reachable on the public API. A client can re-encode a
legitimately-issued v1 handle's (queue_gen, message_id,
receipt_token) under the v2 layout, and DeleteMessage /
ChangeMessageVisibility will accept it (downstream validation
only checks queue_gen + receipt_token). The behaviour is
technically correct (the v1 keyspace lookup still finds the
message) but it leaks the new wire format before PR 5b lands —
breaking the "no behavior change yet" guarantee.
Fix
decodeClientReceiptHandle wraps decodeReceiptHandle with the
dormancy gate: any v2 handle on the public API surfaces as
ReceiptHandleIsInvalid until PR 5b's queue-aware version replaces
the gate (v1 required on non-partitioned queues, v2 required on
partitioned ones).
Changed call sites
Three public-API decode points switch from decodeReceiptHandle
to decodeClientReceiptHandle:
- parseQueueAndReceipt (sqs_messages.go) — DeleteMessage and
ChangeMessageVisibility entry point.
- DeleteMessageBatch entry decode (sqs_messages_batch.go).
- ChangeMessageVisibilityBatch entry decode (sqs_messages_batch.go).
The low-level decodeReceiptHandle keeps working as a pure codec
so the existing v1 + v2 round-trip tests keep passing.
Tests
- TestDecodeClientReceiptHandle_AcceptsV1: v1 handles flow
through unchanged.
- TestDecodeClientReceiptHandle_RejectsV2: a v2 handle on the
public API surfaces as the dormancy-gate error. The
low-level decoder still accepts it (the gate is at the API
boundary, not in the codec).
- TestDecodeClientReceiptHandle_PassesThroughDecodeErrors: a
decode-step error (e.g. base64 garbage) is NOT masked by
the dormancy-gate message — operators see the underlying
error.
Audit per the lessons-learned discipline
The semantic change here is the rejection contract for v2
handles on the public API. grep -rn "decodeReceiptHandle"
across adapter/ showed 3 production call sites (parseQueueAndReceipt,
DeleteMessageBatch, ChangeMessageVisibilityBatch). All 3 updated.
The v2 codec round-trip tests intentionally keep using
decodeReceiptHandle directly so they exercise the codec, not
the public API.
Note on Gemini's "appendU32 is undefined" finding (round 2)
False positive. appendU32 is defined in adapter/sqs_keys.go:444
and has been since PR #703 merged. Gemini did not search across
files in the package; CI build is green and the round-1 v2
round-trip tests exercise the function. No code change needed.1 parent 42c9894 commit c15d801
3 files changed
Lines changed: 109 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
368 | 368 | | |
369 | 369 | | |
370 | 370 | | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
371 | 413 | | |
372 | 414 | | |
373 | 415 | | |
| |||
1494 | 1536 | | |
1495 | 1537 | | |
1496 | 1538 | | |
1497 | | - | |
| 1539 | + | |
1498 | 1540 | | |
1499 | 1541 | | |
1500 | 1542 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
467 | 467 | | |
468 | 468 | | |
469 | 469 | | |
470 | | - | |
| 470 | + | |
471 | 471 | | |
472 | 472 | | |
473 | 473 | | |
| |||
567 | 567 | | |
568 | 568 | | |
569 | 569 | | |
570 | | - | |
| 570 | + | |
571 | 571 | | |
572 | 572 | | |
573 | 573 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
264 | 264 | | |
265 | 265 | | |
266 | 266 | | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
0 commit comments