fix(cran): v3.1.1 — clear gcc-UBSAN additional issue (varPro test skip + vignette precompute)#119
Conversation
…1.1) CRAN's gcc-UBSAN additional check flagged 3.1.0 with a 0-length array access in randomForestSRC's compiled rfsrcGrow (entry.c:184), reached when varPro::varpro()/beta.varpro() grow a forest in our tests. ggRandomForests is pure R (NeedsCompilation: no) — the overflow is in a dependency, surfaced by our tests. Gate every varPro forest-growing test fixture/builder with testthat::skip_on_cran() so CRAN's machines (incl. gcc-UBSAN) never run them. No package code changed; the tests still run on CI and locally. Bump to 3.1.1; NEWS + cran-comments explain the fix. Upstream reported. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #119 +/- ##
=======================================
Coverage 87.04% 87.04%
=======================================
Files 44 44
Lines 3938 3938
=======================================
Hits 3428 3428
Misses 510 510 🚀 New features to boost your workflow:
|
The varpro vignette grew ~10 varPro forests live (varpro/uvarpro/isopro/ ivarpro/beta.varpro), each reaching randomForestSRC's rfsrcGrow rule-grow path that trips the gcc-UBSAN "0-length array" report (entry.c:184, a length-0 yvar.wt decremented to an out-of-bounds pointer). Cache every fit in vignettes/varpro_precomputed.rds and load it with a live fallback, so R CMD check performs no live varPro grow. Strip the unused embedded forests ($rf, $isoforest, redundant ivarpro attrs) before saving — validated that every gg_* wrapper call returns output identical to the un-stripped object — keeping the file at 414 KB (tarball 4.13 MB, under CRAN's 5 MB limit). R CMD check --as-cran (with manual): 0 errors, 0 warnings, 1 NOTE (days-since-update, expected). Overall check time 2:43. dev/randomForestSRC-ubsan-report.md records the upstream root cause + suggested patch (maintainers are aware and staging a fix). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR prepares ggRandomForests v3.1.1 for CRAN by avoiding an upstream randomForestSRC gcc-UBSAN “additional issue” that is surfaced when ggRandomForests exercises varPro forest growth during checks.
Changes:
- Skip varPro-growing tests on CRAN via
testthat::skip_on_cran(). - Precompute all varPro vignette fits into
vignettes/varpro_precomputed.rdsand load them with live fallbacks to avoid any live varPro grow duringR CMD check. - Update release metadata and CRAN-facing documentation (DESCRIPTION/NEWS/cran-comments) and add an upstream UBSAN report note under
dev/.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| vignettes/varpro.qmd | Loads precomputed varPro fits (with fallback) to avoid live forest growth during vignette rebuilds. |
| vignettes/precompute_varpro.R | Script to generate and trim the precomputed vignette objects saved to varpro_precomputed.rds. |
| tests/testthat/test_gg_varpro.R | Skips varPro-based gg_varpro tests on CRAN. |
| tests/testthat/test_gg_udependent.R | Skips varPro-based gg_udependent tests on CRAN. |
| tests/testthat/helper-varpro-fixtures.R | Skips varPro fixture generation on CRAN to avoid triggering upstream UBSAN. |
| NEWS.md | Bumps version to 3.1.1 and documents the CRAN workaround approach. |
| dev/randomForestSRC-ubsan-report.md | New developer note describing the upstream UBSAN issue and suggested patch. |
| DESCRIPTION | Version/date bump for the 3.1.1 release. |
| cran-comments.md | CRAN submission notes updated to explain the UBSAN workaround and test/vignette changes. |
Comments suppressed due to low confidence (1)
tests/testthat/helper-varpro-fixtures.R:12
- Adding
skip_on_cran()here will also skip these fixtures under CIR CMD checkunlessNOT_CRAN=trueis set. With the current workflow env, gg_beta_varpro-related tests that rely on these helpers will no longer run in CI either.
.varpro_mtcars <- function() {
testthat::skip_on_cran()
if (is.null(.varpro_cache$v)) {
if (!requireNamespace("varPro", quietly = TRUE)) {
testthat::skip("varPro not installed")
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Lint CI flagged 16 brace_linter/semicolon_linter issues in the vignette hardening: - varpro.qmd: the load-with-fallback chunks braced the `if` branch but not `else` (`} else .vp$x`); brace both branches to match the existing precomputed chunks. - precompute_varpro.R: rewrite the one-line .strip_* helpers (compound semicolons + inline braces) as multi-line. Behaviour-preserving; lint_package() now returns 0. The shipped varpro_precomputed.rds is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot flagged that skip_on_cran() also skips under R CMD check in CI (NOT_CRAN unset in the workflows), so the varPro tests run nowhere in CI: - NEWS.md / cran-comments.md no longer claim the tests "run on CI"; they state the tests run locally (devtools::test()) and are skipped under R CMD check, including the CI check jobs. (Restoring CI coverage via NOT_CRAN=true is deferred to 3.1.2, coupled with the issue #118 fix so the intermittent survival gg_varpro test doesn't flake CI.) - precompute_varpro.R: scope the "forests unused" comments — the survival C-path gg_partial_varpro() and gg_isopro(newdata=) DO use $rf/$isoforest, but the vignette never invokes those on a stripped object (pd_pbc cached, gg_isopro training-path only). No behaviour change; lint_package() = 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot noted skip_on_cran() also skips the varPro tests under R CMD check in CI (NOT_CRAN unset), so they ran nowhere. Set NOT_CRAN=true in all check/coverage workflows to restore that coverage. Safe: CI is not a sanitizer build, so the upstream randomForestSRC UBSAN path is harmless here; only CRAN's own check machines (NOT_CRAN unset) skip them, which is what avoids the gcc-UBSAN additional issue. The CI-run varPro tests cover regression + classification only (no survival), so issue #118 cannot flake CI. Verified locally under NOT_CRAN=true: 0 failures across the varPro suite. NEWS.md / cran-comments.md restore the accurate "runs in CI and locally; skipped only on CRAN" claim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Resolved the Copilot review threads — all addressed in commits after the review (which ran against
Also fixed the lint failure ( |
Why
CRAN flagged a gcc-UBSAN additional issue on ggRandomForests 3.1.0 (Ripley, 2026-06-12; correct before 2026-06-29):
Root cause is upstream, in
randomForestSRC(not us):rfsrcGrowdoesRF_yWeight = REAL(yWeight); RF_yWeight--unconditionally. Whenyvar.wtarrives length-0 (the unsupervised family path every varPro rule-grow uses),REAL()returns R's0x1empty-vector sentinel and the--forms an out-of-bounds pointer — UB that UBSAN flags (the pointer is never dereferenced). ggRandomForests is pure R (NeedsCompilation: no); it only surfaces the path by exercising varPro. Upstream maintainers are aware and staging a fix; root cause + suggested patch indev/randomForestSRC-ubsan-report.md.What this PR does
skip_on_cran(), so they don't run on CRAN's check machines (incl. gcc-UBSAN). The memtest that flagged 3.1.0 ran only the test suite, so this resolves the reported issue.varprovignette grew ~10 varPro forests live (varpro/uvarpro/isopro/ivarpro/beta.varpro). All are now precomputed intovignettes/varpro_precomputed.rdsand loaded with a live fallback, soR CMD checkperforms no live varPro grow anywhere. Unused embedded forests ($rf,$isoforest, redundantivarproattrs) are stripped before saving — validated that everygg_*wrapper call returns output identical to the un-stripped object — keeping the file at 414 KB and the tarball at 4.13 MB (< CRAN's 5 MB).Verification
R CMD check --as-cranwith manual: 0 errors, 0 warnings, 1 NOTE (days-since-update, expected and pre-explained in cran-comments).--run-donttest/ tests / vignette rebuild: all OK.urlcheckerclean; 0 reverse deps; DESCRIPTION ↔ NEWS both 3.1.1.Residual (intentional)
The
.RdvarPro examples remain\donttest{}+requireNamespace()-guarded (the standard idiom). They run only under--run-donttest, not on normal CRAN checks, and were not the memtest trigger.🤖 Generated with Claude Code