Browse Source

core: remove unused fzf dependency to address CVE

- Eliminates fzf binary dependency that was no longer used after file search overhaul
- Removes fzf from Nix package configuration and Arch Linux PKGBUILD dependencies
Aiden Cline 4 months ago
parent
commit
654a2cd6a4
3 changed files with 4 additions and 128 deletions
  1. 2 2
      nix/opencode.nix
  2. 2 2
      packages/opencode/script/publish.ts
  3. 0 124
      packages/opencode/src/file/fzf.ts

+ 2 - 2
nix/opencode.nix

@@ -1,4 +1,4 @@
-{ lib, stdenvNoCC, bun, fzf, ripgrep, makeBinaryWrapper }:
+{ lib, stdenvNoCC, bun, ripgrep, makeBinaryWrapper }:
 args:
 let
   scripts = args.scripts;
@@ -97,7 +97,7 @@ stdenvNoCC.mkDerivation (finalAttrs: {
     makeWrapper ${bun}/bin/bun $out/bin/opencode \
       --add-flags "run" \
       --add-flags "$out/lib/opencode/dist/src/index.js" \
-      --prefix PATH : ${lib.makeBinPath [ fzf ripgrep ]} \
+      --prefix PATH : ${lib.makeBinPath [ ripgrep ]} \
       --argv0 opencode
 
     runHook postInstall

+ 2 - 2
packages/opencode/script/publish.ts

@@ -90,7 +90,7 @@ if (!Script.preview) {
     "license=('MIT')",
     "provides=('opencode')",
     "conflicts=('opencode')",
-    "depends=('fzf' 'ripgrep')",
+    "depends=('ripgrep')",
     "",
     `source_aarch64=("\${pkgname}_\${pkgver}_aarch64.tar.gz::https://github.com/sst/opencode/releases/download/v\${pkgver}\${_subver}/opencode-linux-arm64.tar.gz")`,
     `sha256sums_aarch64=('${arm64Sha}')`,
@@ -120,7 +120,7 @@ if (!Script.preview) {
     "license=('MIT')",
     "provides=('opencode')",
     "conflicts=('opencode-bin')",
-    "depends=('fzf' 'ripgrep')",
+    "depends=('ripgrep')",
     "makedepends=('git' 'bun-bin' 'go')",
     "",
     `source=("opencode-\${pkgver}.tar.gz::https://github.com/sst/opencode/archive/v\${pkgver}\${_subver}.tar.gz")`,

+ 0 - 124
packages/opencode/src/file/fzf.ts

@@ -1,124 +0,0 @@
-import path from "path"
-import { Global } from "../global"
-import fs from "fs/promises"
-import z from "zod"
-import { NamedError } from "@opencode-ai/util/error"
-import { lazy } from "../util/lazy"
-import { Log } from "../util/log"
-import { ZipReader, BlobReader, BlobWriter } from "@zip.js/zip.js"
-
-export namespace Fzf {
-  const log = Log.create({ service: "fzf" })
-
-  const VERSION = "0.62.0"
-  const PLATFORM = {
-    darwin: { extension: "tar.gz" },
-    linux: { extension: "tar.gz" },
-    win32: { extension: "zip" },
-  } as const
-
-  export const ExtractionFailedError = NamedError.create(
-    "FzfExtractionFailedError",
-    z.object({
-      filepath: z.string(),
-      stderr: z.string(),
-    }),
-  )
-
-  export const UnsupportedPlatformError = NamedError.create(
-    "FzfUnsupportedPlatformError",
-    z.object({
-      platform: z.string(),
-    }),
-  )
-
-  export const DownloadFailedError = NamedError.create(
-    "FzfDownloadFailedError",
-    z.object({
-      url: z.string(),
-      status: z.number(),
-    }),
-  )
-
-  const state = lazy(async () => {
-    let filepath = Bun.which("fzf")
-    if (filepath) {
-      log.info("found", { filepath })
-      return { filepath }
-    }
-    filepath = path.join(Global.Path.bin, "fzf" + (process.platform === "win32" ? ".exe" : ""))
-
-    const file = Bun.file(filepath)
-    if (!(await file.exists())) {
-      const archMap = { x64: "amd64", arm64: "arm64" } as const
-      const arch = archMap[process.arch as keyof typeof archMap] ?? "amd64"
-
-      const config = PLATFORM[process.platform as keyof typeof PLATFORM]
-      if (!config) throw new UnsupportedPlatformError({ platform: process.platform })
-
-      const version = VERSION
-      const platformName = process.platform === "win32" ? "windows" : process.platform
-      const filename = `fzf-${version}-${platformName}_${arch}.${config.extension}`
-      const url = `https://github.com/junegunn/fzf/releases/download/v${version}/${filename}`
-
-      const response = await fetch(url)
-      if (!response.ok) throw new DownloadFailedError({ url, status: response.status })
-
-      const buffer = await response.arrayBuffer()
-      const archivePath = path.join(Global.Path.bin, filename)
-      await Bun.write(archivePath, buffer)
-      if (config.extension === "tar.gz") {
-        const proc = Bun.spawn(["tar", "-xzf", archivePath, "fzf"], {
-          cwd: Global.Path.bin,
-          stderr: "pipe",
-          stdout: "pipe",
-        })
-        await proc.exited
-        if (proc.exitCode !== 0)
-          throw new ExtractionFailedError({
-            filepath,
-            stderr: await Bun.readableStreamToText(proc.stderr),
-          })
-      }
-      if (config.extension === "zip") {
-        const zipFileReader = new ZipReader(new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()])))
-        const entries = await zipFileReader.getEntries()
-        let fzfEntry: any
-        for (const entry of entries) {
-          if (entry.filename === "fzf.exe") {
-            fzfEntry = entry
-            break
-          }
-        }
-
-        if (!fzfEntry) {
-          throw new ExtractionFailedError({
-            filepath: archivePath,
-            stderr: "fzf.exe not found in zip archive",
-          })
-        }
-
-        const fzfBlob = await fzfEntry.getData(new BlobWriter())
-        if (!fzfBlob) {
-          throw new ExtractionFailedError({
-            filepath: archivePath,
-            stderr: "Failed to extract fzf.exe from zip archive",
-          })
-        }
-        await Bun.write(filepath, await fzfBlob.arrayBuffer())
-        await zipFileReader.close()
-      }
-      await fs.unlink(archivePath)
-      if (process.platform !== "win32") await fs.chmod(filepath, 0o755)
-    }
-
-    return {
-      filepath,
-    }
-  })
-
-  export async function filepath() {
-    const { filepath } = await state()
-    return filepath
-  }
-}