From 97fd9393552f9ca0f76217ac268198d058ebcbed Mon Sep 17 00:00:00 2001 From: Arpit Jain <3242828+arpitjain099@users.noreply.github.com> Date: Wed, 23 Sep 2026 10:07:57 -0400 Subject: [PATCH] fix(haskell): do not slice past the end of a stack.yaml rev pin (#5310) An extra-dep can be pinned as "@sha256:," or as "@rev:". The hash slice assumed the first form, so a rev pin left the end index at -1 and the parser panicked with slice bounds out of range. A rev pin carries no package hash, so only the sha256 form now yields one. Signed-off-by: Arpit Jain --- syft/pkg/cataloger/haskell/parse_stack_lock.go | 8 ++++++-- syft/pkg/cataloger/haskell/parse_stack_yaml_test.go | 11 +++++++++++ syft/pkg/cataloger/haskell/testdata/stack.yaml | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/syft/pkg/cataloger/haskell/parse_stack_lock.go b/syft/pkg/cataloger/haskell/parse_stack_lock.go index 90c25d02e..1f36ea424 100644 --- a/syft/pkg/cataloger/haskell/parse_stack_lock.go +++ b/syft/pkg/cataloger/haskell/parse_stack_lock.go @@ -91,8 +91,12 @@ func parseStackPackageEncoding(pkgEncoding string) (name, version, hash string) encodingSplits := strings.Split(remainingEncoding, "@") version = encodingSplits[0] if len(encodingSplits) > 1 { - startHash, endHash := strings.Index(encodingSplits[1], ":")+1, strings.Index(encodingSplits[1], ",") - hash = encodingSplits[1][startHash:endHash] + // a pin is either "@sha256:," or "@rev:", and only the first carries a + // hash. without the comma the end index is -1 and the slice below goes out of range. + colonIdx, commaIdx := strings.Index(encodingSplits[1], ":"), strings.Index(encodingSplits[1], ",") + if colonIdx != -1 && commaIdx > colonIdx { + hash = encodingSplits[1][colonIdx+1 : commaIdx] + } } return } diff --git a/syft/pkg/cataloger/haskell/parse_stack_yaml_test.go b/syft/pkg/cataloger/haskell/parse_stack_yaml_test.go index 853381d07..449276af2 100644 --- a/syft/pkg/cataloger/haskell/parse_stack_yaml_test.go +++ b/syft/pkg/cataloger/haskell/parse_stack_yaml_test.go @@ -102,6 +102,17 @@ func TestParseStackYaml(t *testing.T) { PkgHash: "e4dc6473faaa75fbd7eccab4e3ee1d651d75bb0e49946ef0b8b751ccde771a55", }, }, + { + Name: "acme-missiles", + Version: "0.3", + PURL: "pkg:hackage/acme-missiles@0.3", + Locations: locationSet, + Language: pkg.Haskell, + Type: pkg.HackagePkg, + Metadata: pkg.HackageStackYamlEntry{ + PkgHash: "", + }, + }, } // TODO: relationships are not under test yet diff --git a/syft/pkg/cataloger/haskell/testdata/stack.yaml b/syft/pkg/cataloger/haskell/testdata/stack.yaml index 8c05906e1..b6a63c4bd 100644 --- a/syft/pkg/cataloger/haskell/testdata/stack.yaml +++ b/syft/pkg/cataloger/haskell/testdata/stack.yaml @@ -12,5 +12,6 @@ extra-deps: - hspec-core-2.9.4@sha256:a126e9087409fef8dcafcd2f8656456527ac7bb163ed4d9cb3a57589042a5fe8,6498 - hspec-discover-2.9.4@sha256:fbcf49ecfc3d4da53e797fd0275264cba776ffa324ee223e2a3f4ec2d2c9c4a6,2165 - stm-2.5.0.2@sha256:e4dc6473faaa75fbd7eccab4e3ee1d651d75bb0e49946ef0b8b751ccde771a55,2314 + - acme-missiles-0.3@rev:0 ghc-options: "$everything": -haddock