module NoirMobileLinker
Overview
Post-analysis pass that links mobile deep-link endpoints (produced by the config-file analyzers from AndroidManifest.xml) to the source code that handles them. For each Android mobile endpoint it:
- resolves the handling component (metadata["via"] / the intent:// component) to its .kt/.java source file,
- adds that file as a
code_pathso the AI-context builder scans the handler body for sinks/guards, and - extracts the handler's 1-hop callees into
endpoint.callees.
The existing AIContext builder then derives sinks/guards/sources from the
handler snippet and callees — no mobile-specific wiring needed there. iOS
endpoints have no per-endpoint via, so the linker discovers central
App/SceneDelegate/SwiftUI handlers and attaches them by deep-link kind.
Defined in:
mobile/linker.crConstant Summary
-
BUNDLE_PARAM_RE =
/\b(?:arguments|requireArguments\(\)|getArguments\(\)|savedStateHandle|extras|intent\.extras|intent\.getExtras\(\))\??\s*\.\s*get(?:String|Int|Integer|Boolean|Long|Float|Double|Char|Byte|Short|Parcelable|Serializable|StringArray|CharSequence|Bundle)?(?:\s*<[^>]+>)?\s*\(\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z_][A-Za-z0-9_.]*))/ -
EXTRA_PARAM_RE =
/\.(?:get\w*Extra|hasExtra)\s*\(\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z_][A-Za-z0-9_.]*))/ -
HANDLER_METHODS =
["onCreate", "onNewIntent", "onStart", "onResume", "onStartCommand", "onHandleIntent", "handleIntent", "handleDeepLink", "onReceive", "onBind", "onCreateView", "onViewCreated"] of ::String -
Methods where an Android component reads its inbound intent / deep link. onCreateView / onViewCreated cover Jetpack Navigation fragment destinations, which receive deep-link path/query values as arguments.
-
PROVIDER_HANDLER_METHODS =
["onCreate", "query", "insert", "update", "delete", "bulkInsert", "openFile", "openAssetFile", "call", "getType", "applyBatch"] of ::String -
ContentProvider entry points. A provider is reached via ContentResolver, so its inbound data (the
uri,selection,selectionArgs, projection) arrives through these methods rather than an Intent —query/openFileare the classic SQL-injection / path-traversal sinks. Kept separate from HANDLER_METHODS so these generic verbs are only scanned for provider components, not grafted onto every activity that happens to have anupdate(). -
QUERY_PARAM_RE =
/\.getQueryParameter\s*\(\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z_][A-Za-z0-9_.]*))/ -
Inputs the handler reads from the inbound deep link.
getQueryParameterreads a real URI query parameter (surfaced as a "query" param, baked into the URL like any other); theget*Extrafamily reads Intent extras (a Bundle, not part of the URI) and is surfaced as the "extra" type.
Class Method Summary
- .apply(endpoints : Array(Endpoint), logger : NoirLogger) : Array(Endpoint)
-
.read_content(path : String) : String | Nil
Content cache may be cold (budget exhausted, or caching disabled in tests); fall back to a direct read per the CodeLocator contract.
Class Method Detail
Content cache may be cold (budget exhausted, or caching disabled in tests); fall back to a direct read per the CodeLocator contract.