Skip to content

feat(aegis-core): Layer 2 Go import alias resolution (PR #17)#17

Merged
wei9072 merged 1 commit into
mainfrom
feat/go-import-alias
May 7, 2026
Merged

feat(aegis-core): Layer 2 Go import alias resolution (PR #17)#17
wei9072 merged 1 commit into
mainfrom
feat/go-import-alias

Conversation

@wei9072
Copy link
Copy Markdown
Owner

@wei9072 wei9072 commented May 7, 2026

Summary

Closes the last gap from PR #10's Go SEC010 dispatch. Previously
`import myrand "math/rand"` parsed as a single import with module
`"math/rand"` and no alias; `resolve_receiver("myrand")`
missed because the last-segment of "math/rand" is "rand", not
"myrand". SEC010 then silently passed `myrand.Intn(...)` even
though it's the same weak RNG.

Two changes

  1. `Import.alias: Option` — new field on the
    `Import` struct in `ast::imports`. Populated when the
    captured path's parent `import_spec` node has a `name`
    field (Go's import-renaming syntax). Filters out `_` (blank
    import) and `.` (dot import) since neither is a usable
    receiver name.
  2. `ParsedFile::resolve_receiver` two-pass lookup:
    • Pass 1: explicit alias match. Aliased imports always win.
    • Pass 2: last-segment / module-name match, but skips
      aliased imports
      — so `rand` no longer falsely resolves
      to a `math/rand` imported as `myrand`.

Tests

  • 5 new in `ast::imports` and `ast::parsed_file`:
    Go aliased / unaliased / blank+dot / alias-preferred /
    mixed-aliased-and-unaliased in same file
  • 2 new end-to-end SEC010 cases:
    `myrand.Intn` (aliased math/rand) → fires
    `crand.Read` (aliased crypto/rand) → does NOT fire

`cargo test --workspace`: 174 / 174 (was 167).

Test plan

🤖 Generated with Claude Code

Closes the last gap from PR #10's Go SEC010 dispatch. Previously
`import myrand "math/rand"` parsed as a single import with module
"math/rand" and no alias; resolve_receiver("myrand") missed
because last-segment of "math/rand" is "rand", not "myrand".
SEC010 then silently passed `myrand.Intn(...)` even though it's
the same weak RNG.

Two changes:

1. **`Import.alias: Option<String>`** — new field on the Import
   struct in `ast::imports`. Populated when the captured path's
   parent `import_spec` node has a `name` field (Go's syntax for
   import renaming). Other languages return None for now.
   Filters out Go's `_` (blank import for side-effects) and `.`
   (dot import) so resolve_receiver doesn't try to match those.

2. **`ParsedFile::resolve_receiver` two-pass lookup**:
   - Pass 1: explicit alias match. Aliased imports always win
     (`myrand` resolves to `math/rand`).
   - Pass 2: last-segment / module-name match, but **skips
     aliased imports** so `rand` no longer falsely resolves to
     a `math/rand` that was imported as `myrand`.

Tests: 5 new — Go aliased import captures alias, Go unaliased
returns None, blank/dot imports skipped, alias preferred over
last-segment, mixed aliased+unaliased in same file.

Plus 2 SEC010 end-to-end tests:
- `myrand.Intn` (aliased math/rand) → fires
- `crand.Read` (aliased crypto/rand) → does NOT fire

Total: 167 → 174 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@wei9072 wei9072 merged commit f90b26f into main May 7, 2026
1 check passed
@wei9072 wei9072 deleted the feat/go-import-alias branch May 7, 2026 08:39
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