Skip to content

R SDK: CRAN pre-submission validation (spelling, R-devel, ASAN/UBSAN)#180

Merged
clemensv merged 5 commits into
masterfrom
chore/r-cran-presubmission
Jul 14, 2026
Merged

R SDK: CRAN pre-submission validation (spelling, R-devel, ASAN/UBSAN)#180
clemensv merged 5 commits into
masterfrom
chore/r-cran-presubmission

Conversation

@clemensv

Copy link
Copy Markdown
Contributor

R SDK: CRAN pre-submission validation

Runs the CRAN pre-submission checks that were still outstanding and adds the
coverage that can't run on the Windows dev box.

Done in this PR

  • Spelling — declare Language: en-US and add inst/WORDLIST so
    spelling::spell_check_package() (which CRAN runs) is clean. The wordlist
    holds only real technical terms (cJSON, ReDoS, enum, matcher, SDK, Rtools,
    vendored, …) and the package's British spellings — no actual typos.
  • R-devel matrix — add 'devel' to the R CMD check --as-cran matrix
    (ubuntu/macos/windows) so we test against the R version CRAN builds with.
  • ASAN/UBSAN sanitizers — new job running R CMD check inside the r-hub
    clang-asan container (R-devel + AddressSanitizer + UndefinedBehaviorSanitizer).
    The shared corpus is enabled so the hand-written C regex matcher
    (src/regex_utils.c) is stressed under the sanitizers along with the engine
    and cJSON. The release job now also gates on this.

Already validated locally (Windows, R 4.6.1)

  • urlchecker::url_check()all URLs correct.
  • R CMD check --as-cran with _R_CHECK_CRAN_INCOMING_REMOTE_=TRUE
    0 errors, 0 warnings, 2 notes: "New submission" (automatic) and the
    documented cJSON -Wcast-qual pragma. No URL / spelling / name / metadata
    findings.

Not automatable here (maintainer action)

  • win-builder (devtools::check_win_devel()) e-mails results to the
    maintainer; run before the final submit.
  • Final submission via the CRAN web form / devtools::release() must be done
    by the maintainer (cre), who confirms via the CRAN e-mail link.

clemensv and others added 5 commits July 14, 2026 10:47
Declare `Language: en-US` in DESCRIPTION and add `inst/WORDLIST` so
`spelling::spell_check_package()` (run by CRAN) is clean. The wordlist
contains only genuine technical terms (cJSON, ReDoS, enum, matcher, SDK,
Rtools, vendored, ...) and the package's British spellings; there are no
actual misspellings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extend pre-submission coverage that cannot be run on the Windows dev box:

* Add 'devel' to the R version matrix so R CMD check --as-cran also runs on
  R-devel (the version CRAN builds against) across ubuntu/macos/windows.
* Add a `sanitizers` job that runs R CMD check inside the r-hub v2
  clang-asan container (R-devel built with AddressSanitizer +
  UndefinedBehaviorSanitizer). The shared conformance corpus is enabled via
  JSONSTRUCTURE_TEST_ASSETS so the hand-written C regex matcher in
  src/regex_utils.c is exercised under the sanitizers alongside the engine
  and cJSON.
* Gate the release tarball job on the sanitizer job as well.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The whole-package r-hub clang-asan container job proved flaky: installing
the package's dependencies (jsonlite/testthat) from the r-hub binary repo
under R-devel intermittently fails on a missing prebuilt, which surfaces as a
"package dependencies ... ERROR" unrelated to memory safety.

Replace it with a deterministic, dependency-free job: compile the hand-written
pure-C matcher (src/regex_utils.c) together with a dedicated harness
(tools/sanitizer/regex_asan.c) using clang -fsanitize=address,undefined
-fno-sanitize-recover=all and run it. The harness stresses valid patterns,
rejected constructs, adversarial ReDoS shapes, long inputs and cache eviction.
This is the only new memory-sensitive C in the R package; the shared engine and
cJSON are already covered by the C SDK's Valgrind job. The harness lives under
tools/ and is excluded from the package tarball via .Rbuildignore.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CRAN's "checking pragmas in C/C++ headers and code" flagged src/cJSON.c for a
`#pragma GCC diagnostic ignored "-Wcast-qual"` (with push/pop) wrapping the
internal cast_away_const() helper. Remove the pragma wrapper, keeping the
helper unchanged.

-Wcast-qual is not part of the flags R uses to compile packages, so the helper
compiles cleanly under -Wall -Wextra with no new warning; the suppression was
purely defensive. Verified with `R CMD check --as-cran`
(_R_CHECK_CRAN_INCOMING_REMOTE_=TRUE): the pragma check is now OK and the
overall result is 0 errors / 0 warnings / 1 note (the unavoidable
"New submission" note).

Document the modification alongside the existing sprintf->snprintf change in
inst/COPYRIGHTS, and update cran-comments.md to reflect the single remaining
note.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The shared C schema engine only validated the direct target of a
`$extends` keyword, so a multi-hop cycle among abstract/unreferenced
definitions (A -> B -> C -> A) was silently accepted. Add
check_extends_cycle(): a bounded visited-set walk over string $extends
links that reports JS_SCHEMA_REF_CIRCULAR on a revisit or excessive
depth, wired into validate_schema_node's $extends block. This makes
circular $extends detectable regardless of whether the type is used.

Add C conformance tests (invalid_circular_extends_chain,
invalid_self_referencing_extends) and re-vendor the fix into r/src.

Bring the R testthat suite to parity with the other SDKs by running the
shared adversarial schema/instance corpus and the warnings corpus,
mirroring python/tests/test_assets.py. This coverage is what surfaced
the engine bug (extends-circular-chain.struct.json).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@clemensv clemensv merged commit 9c8f0d2 into master Jul 14, 2026
25 checks passed
@clemensv clemensv deleted the chore/r-cran-presubmission branch July 14, 2026 10:52
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.

1 participant