Skip to content

Managed limits for pathological dice notation (overflow, huge rolls)#526

Merged
ianfhunter merged 15 commits intomainfrom
cursor/roll-input-validation-63f3
Mar 30, 2026
Merged

Managed limits for pathological dice notation (overflow, huge rolls)#526
ianfhunter merged 15 commits intomainfrom
cursor/roll-input-validation-63f3

Conversation

@ianfhunter
Copy link
Copy Markdown
Owner

@ianfhunter ianfhunter commented Mar 30, 2026

Description

Pathological strings such as very long decimal literals or enormous XdY counts could stress GNOLL. Bounds checking is implemented in gnoll_validate_roll_request (roll_validation.c) and roll_full_options calls it before lex/parse. roll_and_write and friends still route through roll_full_options, so existing FFI entry points remain protected.

Language bindings were updated so callers can pre-check without rolling (and examples document the pattern):

  • C API: gnoll_validate_roll_request(const char *); gnoll_validate_roll_request_R for R’s .C() pattern (sets *return_code).
  • Java: DiceNotationParser.validateRollRequest; JNI releases UTF-8 strings after roll; Test.java asserts validate.
  • JS/WASM: Emscripten exports _gnoll_validate_roll_request; validateRollRequest() in gnoll.js.
  • Go, Haskell, Rust, Ruby, Lua, PHP, C#, C++: examples call validate before roll / check roll_and_write return codes where applicable.
  • Julia: validate_roll_request; roll(s) now uses s (previous bug: hardcoded "1d20"); tests cover validate.
  • R: gnoll_validate_roll_request_R + main.r uses shared notation for validate and roll.

Python: validate_roll_string wraps C via ctypes; roll_full_options ctypes use correct types (c_longlong seed, int flags).

Build: Makefile ties generated yacc/lex outputs to grammar sources so dice.so cannot go stale.

How Has This Been Tested

  • make test152 passed, 9 skipped

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Test Coverage (Additional test(s) without any extra code)
  • Code Quality / Maintenance

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation & I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I give my permission for my code to be used in this project under this license and any future license terms
Open in Web Open in Cursor 

cursoragent and others added 2 commits March 30, 2026 09:14
- Lexer: parse NUMBER with strtol (ERANGE) and max token length; yyterminate on error
- Core: refuse rolls above GNOLL_MAX_DICE_PER_ROLL when not using CLT
- Remove unsafe fast_atoi that wrapped on overflow
- Centralize GNOLL_MAX_* limits in shared_header.h

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
- validate_roll_string mirrors lexer/dice limits for defense in depth
- Lazy-load dice.so so validation can be imported without a build
- Add tests for huge literals and extreme XdY counts

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
@ianfhunter
Copy link
Copy Markdown
Owner Author

ianfhunter commented Mar 30, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions github-actions Bot added the core label Mar 30, 2026
deepsource-autofix Bot and others added 9 commits March 30, 2026 09:15
This commit fixes the style issues introduced in fc6514a according to the output
from Autopep8, Black, Go fmt, Gofumpt, isort and Yapf.

Details: #526
- Avoid free(NULL) / use-after-free when perform_roll returns NULL (e.g. dice cap)
- Free symbolic symbol pool before return on failed do_roll
- Add boundary and native-path tests; patch validation module for bypass tests

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
This commit fixes the style issues introduced in e350a86 according to the output
from Autopep8, Black, Go fmt, Gofumpt, isort and Yapf.

Details: #526
- pytest from repo root finds src/python/code without PYTHONPATH
- make test refreshes c_build via python target and skips pip wheel install

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
This commit fixes the style issues introduced in 07ac41c according to the output
from Autopep8, Black, Go fmt, Gofumpt, isort and Yapf.

Details: #526
- Add gnoll_validate_roll_request in roll_validation.c (digit test via '0'/'9')
- Call from roll_full_options before lex/parse; export in shared_header.h
- Remove Python validation.py; validate_roll_string wraps C via ctypes
- Fix roll_full_options ctypes signature (c_longlong seed, int flags)
- Makefile: yacc/lex outputs depend on grammar sources; y.tab.o/lex.yy.o depend on generated .c

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
This commit fixes the style issues introduced in 9faff0f according to the output
from Autopep8, Black, Go fmt, Gofumpt, isort and Yapf.

Details: #526
- C: gnoll_validate_roll_request_R for R .C() pattern; declare in shared_header.h
- Java: validateRollRequest JNI + UTF-8 release in roll; Test asserts validate
- JS/WASM: export _gnoll_validate_roll_request; validateRollRequest() helper
- Go, Haskell, Rust, Ruby, Lua, PHP, C#, C++: call validate before roll where shown
- Julia: fix roll() to use argument s; add validate_roll_request; test validate
- Ruby/Lua: use int return from roll_and_write and check errors

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
…iases

- Haskell: extra-lib-dirs ../../build + extra-libraries dice (not path as library name)
- Rust: add build.rs for rustc-link-search/lib; drop invalid Cargo [build] table
- Rust target.mk: set LIBRARY_PATH to build dir (was literal $LD_LIBRARY_PATH)
- Webpack: alias node:fs and node:crypto to browserify shims for gnollwasm.js
- Rust: merge unsafe blocks to silence unused_unsafe warning

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
…lib copy

- Haskell: ccall imports are pure CInt; use let not <- in IO do-block
- Haskell: copy libdice.so to src/haskell/lib for extra-lib-dirs inside tree
- Webpack: NormalModuleReplacementPlugin for node:fs and node:crypto (alias failed)
- Drop sudo cp to /usr/lib from haskell target

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
@ianfhunter ianfhunter marked this pull request as ready for review March 30, 2026 11:26
cursoragent and others added 2 commits March 30, 2026 17:33
- cabal build with -optl-Wl,-rpath,<abs>/src/haskell/lib so runtime finds libdice
- Set LD_LIBRARY_PATH for linker subprocess if needed
- main: pattern match on getArgs instead of head

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
- Generate cabal.project.local with ghc-options rpath so cabal run relinks correctly
- CI: export LD_LIBRARY_PATH to src/haskell/lib before cabal run (belt and suspenders)

Co-authored-by: Ian Hunter <ianfhunter@users.noreply.github.com>
@ianfhunter ianfhunter merged commit d9c57f2 into main Mar 30, 2026
22 of 31 checks passed
@ianfhunter ianfhunter deleted the cursor/roll-input-validation-63f3 branch March 30, 2026 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants