Repository navigation
fix: mf_getvalue edge case - #459
Conversation
There was a problem hiding this comment.
Reviewed the full base...head diff at 377d03d (base/mf_getvalue.sas, generated all.sas, tests/base/mf_getvalue.test.sas) plus repo hardening state. The %syscall set -> explicit getvarN/getvarC rework fixes the global-macro-variable collision correctly, all.sas is in sync with the source macro, and the new Test 9 covers the regression. Findings:
-
base/mf_getvalue.sas:60-66 - behavior change worth confirming before merge: values previously flowed through %syscall set(dsid) (CALL SET), which applies the variable's assigned format when populating the macro value; %sysfunc(getvarn()) returns the raw numeric. For a numeric column with e.g. date9. attached, the returned value changes from the formatted string to the underlying SAS date number. If any caller relies on the formatted representation this is a silent breaking change - either preserve the format (read it via varfmt() and wrap with putc()) or state the change explicitly in the PR description.
-
CI: the SAS test suite has not executed on any commit of this PR. The Node.js CI run at 76a7c15 failed in the "Start Open VPN 3" step (VPN infra, all build/test steps skipped), and the run at the current head 377d03d sits at action_required awaiting workflow approval (triggered by the all.sas automation commit). Request approval or rerun so the new getvarN/getvarC path is exercised by the full suite in CI, not only locally.
-
.npmrc - has ignore-scripts=true but is missing save-exact=true; add it so local installs cannot reintroduce ^/~ ranges.
-
No npm audit step in any workflow (.github/workflows/run-tests.yml, main.yml, notmain.yml). The Snyk PR check scans dependencies, but the pipeline itself has no audit gate that fails the build - add
npm audit(default level) as a failing step. -
.git-hooks/pre-commit ships a pinned gitleaks staged scan, but since the install-time prepare script was dropped nothing wires it up (no
git config core.hooksPath ./.git-hooksstep and no docs mention it), so a fresh clone activates no hooks and the secret scan is dormant. Wire the hooksPath into setup/docs or CI, or move to a .pre-commit-config.yaml gitleaks hook.
5 findings above for review.
Addresses the review findings on repo hardening: - .npmrc: add save-exact so local installs cannot reintroduce ^/~ ranges - run-tests.yml: scan for secrets with the pinned gitleaks binary and run npm audit as a failing step - main.yml: run npm audit before release - CONTRIBUTING.md: document `git config core.hooksPath ./.git-hooks`; the hooks are inert until that is set, so a fresh clone commits unscanned
Two changes so the review findings are observable in CI: - run-tests.yml: move npm ci, the gitleaks scan, npm audit and lint ahead of the VPN steps, so they report even when the tunnel is down. The SAS suite is currently blocked by the VPN step timing out, which skips every later step. - notmain.yml: drop --allow-empty so an unchanged all.sas produces no commit. The empty bot commit made the PR head a run that needs manual approval, which is what kept the SAS suite from executing on the head.
|
Follow-up on the five review findings (head Format behaviour change ( CI - the SAS test suite - approved the pending run and reran it. It fails at Two CI-side fixes landed in this PR so the findings are observable:
The SAS suite itself still needs the tunnel to come up. That is infrastructure, not this repo. .npmrc - npm audit - added as a failing step to .git-hooks - |
There was a problem hiding this comment.
Re-review at 271251c, superseding the review at 377d03d. Scope: the delta since the prior review (the CI/hardening commits bd56671 and 271251c, .npmrc, CONTRIBUTING.md) plus the unchanged mf_getvalue change at the new head; verified all.sas is in sync with base/mf_getvalue.sas and the squash subject ("fix: mf_getvalue edge case") is a release-driving conventional commit.
-
.github/workflows/run-tests.yml:70 - the pipeline is red at this head: the test job fails at "Start Open VPN 3" (the 1-minute timeout fires; the session is created but never connects) and every step after it is skipped, so "Run all tests" at run-tests.yml:119 never executes and the new getvarN/getvarC path is unexercised in CI. The static gates moved ahead of the VPN all pass, and the failure is pre-existing infrastructure - every run-tests run back to 2026-09-15 fails identically - so it is not introduced by this PR's code. Decide at merge: accept the local sasjs test evidence in the PR description, or hold until the tunnel is fixed so the suite covers the new code path.
-
base/mf_getvalue.sas:60-66 - the format behavior change from the prior review is still in the diff: the old CALL SET path applied the variable's assigned format when materializing the macro value, while %sysfunc(getvarN()) returns the raw numeric, so a numeric column with e.g. date9. attached now returns the underlying SAS date number instead of the formatted string. Deferred to a separate change per the thread; restated here so the record at this head carries it as a known, intentional behavior change.
2 findings above for review.
|
🎉 This PR is included in version 5.3.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Issue
basemacromf_getvaluecan accidentally return a value in error when a populated global macro variable exists with an identical name to the variable name being requested from input data that yields no eligible row to performfetchobs()upon.Code:
Log:
80 data sample; 81 key = 0; 82 VarA = "xyz"; 83 run; NOTE: The data set WORK.SAMPLE has 1 observations and 2 variables. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds 84 85 %let VarA = "abc"; 86 87 %let stored_val = %mf_getvalue(sample,VarA,filter=(key > 0)); WARNING: End of file. 88 89 %put NOTE: &=stored_val; NOTE: STORED_VAL="abc"Intent
Rejig the current column extraction method which turns all variables in the data vector into equivalent macro variables.
Implementation
Replace
%syscall set( )-based method with explicit query for the requested column.Checks
sasjs lint).sasjs test) (see below).