Skip to content

Issue with tarballs - artifactResultsToAlerts #44

Description

@OnePieceNZ

Bug: artifactResultsToAlerts crashes on packages without alerts

Location

sfw-free binary v1.8.0, in the bundled JS at the function registered as
artifactResultsToAlerts (minified name: n_).

The function (decompiled)

function artifactResultsToAlerts(results) {
  return results
    .flatMap(pkg => pkg.alerts.map(alert => ({
      ...alert,
      inputPurl: pkg.inputPurl ?? "",
      packageName: pkg.name,
      packageType: pkg.type,
      packageVersion: pkg.version,
    })))
    .filter(a => a.action === "error" || a.action === "warn");
}

The bug

The schema (Cc) defines alerts as optional:

alerts: s.array(W1).optional()

So when the Socket API returns a package result where alerts is undefined
(which happens for private/scoped packages like @private/* that aren't in their
database), the code does:

pkg.alerts.map(...)
//  ^^^^^^ undefined

This throws:

TypeError: Cannot read properties of undefined (reading 'map')

Call chain

  1. npm CONNECT request intercepted by sfw-free proxy
  2. fetchBlockStatusgetPurlAlertInfoZg (fetchAlerts) → t_ (fetchFreeAlerts)
  3. t_ calls o_ or i_ which are API wrappers created by dr(url, method, params, schema, parser, transform)
  4. n_ (artifactResultsToAlerts) is passed as the transform (6th arg) to dr
  5. Inside dr, after successful schema validation: return [o ? o(P) : P, null]
  6. So n_(validatedResults) is called — crashes if any result has alerts: undefined

Impact

The TypeError propagates up, killing the proxy CONNECT handler. npm sees
ECONNRESET on the tarball download socket.

Fix

function artifactResultsToAlerts(results) {
  return results
    .flatMap(pkg => (pkg.alerts ?? []).map(alert => ({
      ...alert,
      inputPurl: pkg.inputPurl ?? "",
      packageName: pkg.name,
      packageType: pkg.type,
      packageVersion: pkg.version,
    })))
    .filter(a => a.action === "error" || a.action === "warn");
}

One-character-class fix: pkg.alerts?.map(...) with .flatMap would also work
since flatMap skips undefined returns, but (pkg.alerts ?? []).map(...) is more
explicit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions