Code Quality: PR #376 #1032
codeql
on: dynamic
Matrix: analyze
Annotations
5 warnings
|
Race condition clears loadPromise before unlink completes, allowing duplicate xcrun invocations:
src/utils/device-name-resolver.ts#L68
In refreshDeviceNames, the IIFE sets `loadPromise = null` in the finally block before awaiting `unlink(tmpFile)`. Because the assignment happens synchronously at the start of the finally, a concurrent caller invoking refreshDeviceNames during the unlink await will see loadPromise as null and a fresh cache, but if the cache check fails for any reason (e.g., the catch branch did not populate it on a TTL boundary), a second xcrun process can be spawned while the first is still cleaning up. More importantly, the deduplication guarantee is weaker than intended — `loadPromise` should remain set for the entire lifetime of the returned promise so awaiters all observe the same in-flight work.
|
|
Race condition: loadPromise cleared before unlink completes allows concurrent refreshes to collide:
src/utils/device-name-resolver.ts#L70
Inside the IIFE's finally block, `loadPromise = null` is set before `await unlink(tmpFile)` runs. Because the tmpFile path includes `Date.now()`, this is mostly safe, but more importantly: setting `loadPromise = null` inside the async finally means any caller that awaits `refreshDeviceNames()` returns before unlink finishes, and a subsequent call entering while unlink is still pending will start a second xcrun invocation rather than dedup. This undermines the stated 'in-flight deduplication' goal and can spawn overlapping subprocesses under load.
|
|
Fire-and-forget refresh via `void refreshDeviceNames()` may surface unhandled promise rejections:
src/utils/device-name-resolver.ts#L84
`ensureDeviceNamesRefresh` discards the returned promise with `void`. While `refreshDeviceNames` catches errors from execFile/readFile internally, any unexpected synchronous throw or future code change inside the IIFE that escapes the try/catch would become an unhandled rejection, which Node may treat as fatal in newer versions. Since `resolveDeviceName` is called from rendering/pipeline code, an unhandled rejection here could crash the process.
|
|
Analyze (python)
Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses.
To opt out of this change, create a custom repository property with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to `true` in the repository's settings.
|
|
Analyze (javascript-typescript)
Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses.
To opt out of this change, create a custom repository property with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to `true` in the repository's settings.
|