Skip to content

feat: recognise entry points by a pattern on the base class - #177

Merged
SizzleUnrlsd merged 2 commits into
mainfrom
feat/base-entry-points
Sep 28, 2026
Merged

SizzleUnrlsd merged 2 commits into
mainfrom
feat/base-entry-points

Conversation

@SizzleUnrlsd

Copy link
Copy Markdown
Contributor

Closes #176. The engine side of the gRPC chantier; the grpc table follows in Enterprise (CoreTrace-Entreprise/coretrace-python-analyzer-plugins#3), with the pattern (?:^|\.)\w+_pb2_grpc\.\w+Servicer$ and the sources on ServicerContext.

Summary

  • BasePattern(pattern, label, parameters=(None,), kinds=ALL). The methods of a class whose base's canonical symbol matches the regular expression are entry points, whatever the module's prefix and however the base is imported: module, module alias, import … as, name, name alias. The generated module may be in the project or absent from it.
  • Parameters by their role. By position after self: None is attacker input of the model's kinds; a class symbol makes the parameter denote that class, so the sources on the class apply, as invocation_metadata() on a ServicerContext, without the object being input: peer() and str(context) give nothing. The message carries every kind, its MessageToDict conversion, attributes and dict literals included.
  • RPC methods only. The arity must match the list. When the project holds the base (its class is a project symbol), only the methods the base defines are entry points, so a servicer's utility methods are not; otherwise every method with that arity is, which the tests document as the limit.
  • Engine wiring. Signature and SignaturesAnalysis in the interprocedural layer, provided from the models at the four sites (single file, project, batch), like ClearingAnalysis. The call graph types the parameters by position for every resolvable base of the class: its inheritance map keeps the first base only, and a mixin or an installed class before the generated base would otherwise hide the context typing. SummaryIndex.defines says whether the project holds a class.
  • Inheritance identifies a potential service; it does not prove the servicer is registered on a server (documented in the model and the guide).

Verification

  • RED: 16 failures for the expected reasons (no finding, no entry point) once the model existed without behaviour; one more RED for the installed-first-base case, then fixed.
  • tests/test_base_patterns.py: 24 passed. Full suite under Python 3.12.10, regression snapshots included: 1434 passed. ruff check and mypy pass.
  • Mutations, all killed: the arity check, the base-defines check, the project-holds-base check, a typed role treated as input, patterns applied to decorators, the signature typing, the signature arity, the batch provisioning, the pattern's anchoring.

A gRPC servicer subclasses a class generated per project, so no fixed symbol
names it. The tests specify a BasePattern model: the methods of a class whose
base's canonical symbol matches the pattern are entry points whatever the
module's prefix and however the base is imported, their parameters typed by
their position (the message is input of every kind, the context denotes a
class whose invocation_metadata() is a text source and whose peer() is not),
only the methods the base defines when the project holds it, and every method
with the listed arity otherwise. Async methods, client streams, other
processes, a single-file check and a base preceded by another are covered.
BasePattern(pattern, label, parameters, kinds) matches the canonical symbol of
a class's base against a regular expression, for bases generated per project
such as a gRPC servicer's. Each parameter after self is, by position, input
of the model's kinds or an object of a class the model names, which the
sources on that class taint without the object being input. When the project
holds the base, only the methods the base defines are entry points, so a
servicer's utility methods are not; otherwise every method with the listed
number of parameters is.

The engine derives Signatures from the models and provides them to the call
graph, which types the parameters by their position for every resolvable base
of the class, since the inheritance map keeps the first base only. The taint
engine decides the entry point with the project index, which says what the
base defines.
@SizzleUnrlsd SizzleUnrlsd added the enhancement New feature or request label Sep 28, 2026
@SizzleUnrlsd SizzleUnrlsd self-assigned this Sep 28, 2026
@SizzleUnrlsd
SizzleUnrlsd merged commit 7a56715 into main Sep 28, 2026
10 checks passed
@SizzleUnrlsd
SizzleUnrlsd deleted the feat/base-entry-points branch September 28, 2026 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Entry points by a pattern on the base class, with the parameters typed by their role

1 participant