Skip to content

Implement limit directive for msgp array/map size bounds checking - #419

Merged
klauspost merged 3 commits into
tinylib:masterfrom
klauspost:marshal-limits
Nov 18, 2025
Merged

klauspost merged 3 commits into
tinylib:masterfrom
klauspost:marshal-limits

Conversation

@klauspost

@klauspost klauspost commented Nov 14, 2025 •

Copy link
Copy Markdown
Collaborator

Add //msgp:limit directive to prevent DoS attacks by limiting array/slice and map sizes during msgp serialization/deserialization operations.

Features:

  • Unified directive syntax: //msgp:limit arrays:n maps:n marshal:true/false
  • Applies only to dynamic slices/maps, excludes fixed arrays (compile-time sized)
  • Optional marshal-time enforcement with marshal:true parameter
  • Default limits of math.MaxUint32 when not specified
  • Returns msgp.ErrLimitExceeded when limits exceeded
  • Per-file unique constant generation using CRC32 hash to avoid collisions

Adds msgp:",limit=n" per field tags. This will allow to set or override a per-file limit.

Note: This also applies to []byte slices.

Usage examples:

//msgp:limit arrays:100 maps:50 (unmarshal limits only)

//msgp:limit arrays:100 maps:50 marshal:true (both marshal and unmarshal limits)

type FieldLimitTestData struct {
	SmallSlice []int          `msg:"small_slice,limit=5"`
	LargeSlice []string       `msg:"large_slice,limit=100"`
	SmallMap   map[string]int `msg:"small_map,limit=3"`
	LargeMap   map[int]string `msg:"large_map,limit=20"`
	NoLimit    []byte         `msg:"no_limit"`  // Uses file-level limits if any
	FixedArray [10]int        `msg:"fixed_array,limit=2"` // Should be ignored

Fixes #411

Add `//msgp:limit` directive to prevent DoS attacks by limiting array/slice and map sizes during msgp serialization/deserialization operations.

Features:
  - Unified directive syntax: //msgp:limit arrays:n maps:n marshal:true/false
  - Applies only to dynamic slices/maps, excludes fixed arrays (compile-time sized)
  - Optional marshal-time enforcement with marshal:true parameter
  - Default limits of math.MaxUint32 when not specified
  - Returns msgp.ErrLimitExceeded when limits exceeded
  - Per-file unique constant generation using CRC32 hash to avoid collisions

Usage examples:

`//msgp:limit arrays:100 maps:50` (unmarshal limits only)

`//msgp:limit arrays:100 maps:50 marshal:true` (both marshal and unmarshal limits)
@klauspost
klauspost requested a review from philhofer November 17, 2025 12:46
@klauspost
klauspost merged commit d6ec98e into tinylib:master Nov 18, 2025
4 checks passed
@klauspost
klauspost deleted the marshal-limits branch November 18, 2025 11:21
gannett-ggreer pushed a commit to GannettDigital/msgp that referenced this pull request Aug 25, 2026
…nylib#419)

Add `//msgp:limit` directive to prevent DoS attacks by limiting array/slice and map sizes during msgp serialization/deserialization operations.

Features:
  - Unified directive syntax: //msgp:limit arrays:n maps:n marshal:true/false
  - Applies only to dynamic slices/maps, excludes fixed arrays (compile-time sized)
  - Optional marshal-time enforcement with marshal:true parameter
  - Default limits of math.MaxUint32 when not specified
  - Returns msgp.ErrLimitExceeded when limits exceeded
  - Per-file unique constant generation using CRC32 hash to avoid collisions

Adds `msgp:",limit=n"` per field tags. This will allow to set or override a per-file limit.

Note: This also applies to `[]byte` slices.

Usage examples:

`//msgp:limit arrays:100 maps:50` (unmarshal limits only)

`//msgp:limit arrays:100 maps:50 marshal:true` (both marshal and unmarshal limits)

```go
type FieldLimitTestData struct {
	SmallSlice []int          `msg:"small_slice,limit=5"`
	LargeSlice []string       `msg:"large_slice,limit=100"`
	SmallMap   map[string]int `msg:"small_map,limit=3"`
	LargeMap   map[int]string `msg:"large_map,limit=20"`
	NoLimit    []byte         `msg:"no_limit"`  // Uses file-level limits if any
	FixedArray [10]int        `msg:"fixed_array,limit=2"` // Should be ignored
```
Fixes tinylib#411
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SetMaxElements equivalent for msgp.Unmarshaler interface

2 participants