From 35884ede281a635dd6eb8541e35481d016e18248 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 11:05:38 +0100 Subject: [PATCH 01/15] Ignore invalid Unicode in pkg-config descriptions Previously, if any of the pkg-config packages on the system had invalid Unicode in their description fields (like the Intel vpl package has at the time of writing, 2024-01-11, see #9608), cabal would crash because it tried to interpret the entire `pkg-config --list-all` output as Unicode. This change, as suggested by gbaz in https://github.com/haskell/cabal/issues/9608#issuecomment-1886120831 switches to using a lazy ByteString for reading in the output, splitting on the first space in byte land, and then parsing only the package _name_ to a String. For further future-proofing, package names that don't parse as valid Unicode don't crash Cabal, but are instead ignored. --- .../cabal-install-solver.cabal | 1 + .../Distribution/Solver/Types/PkgConfigDb.hs | 23 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index fe440a78963..fa8be754ae7 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -110,6 +110,7 @@ library , mtl >=2.0 && <2.4 , pretty ^>=1.1 , transformers >=0.4.2.0 && <0.7 + , text if flag(debug-expensive-assertions) cpp-options: -DDEBUG_EXPENSIVE_ASSERTIONS diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index ee2f22032ca..11a67112cf9 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -23,17 +23,22 @@ module Distribution.Solver.Types.PkgConfigDb import Distribution.Solver.Compat.Prelude import Prelude () -import Control.Exception (handle) -import Control.Monad (mapM) -import qualified Data.Map as M -import System.FilePath (splitSearchPath) +import Control.Exception (handle) +import Control.Monad (mapM) +import qualified Data.ByteString.Lazy as LBS +import Data.Either (rights) +import qualified Data.Map as M +import qualified Data.Text as T +import qualified Data.Text.Encoding as T +import System.FilePath (splitSearchPath) import Distribution.Compat.Environment (lookupEnv) import Distribution.Package (PkgconfigName, mkPkgconfigName) import Distribution.Parsec import Distribution.Simple.Program (ProgramDb, getProgramOutput, pkgConfigProgram, needProgram, ConfiguredProgram) -import Distribution.Simple.Program.Run (getProgramInvocationOutputAndErrors, programInvocation) +import Distribution.Simple.Program.Run + (getProgramInvocationOutputAndErrors, programInvocation, getProgramInvocationLBS) import Distribution.Simple.Utils (info) import Distribution.Types.PkgconfigVersion import Distribution.Types.PkgconfigVersionRange @@ -63,10 +68,14 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do case mpkgConfig of Nothing -> noPkgConfig "Cannot find pkg-config program" Just (pkgConfig, _) -> do - pkgList <- lines <$> getProgramOutput verbosity pkgConfig ["--list-all"] + -- To prevent malformed Unicode in the descriptions from crashing cabal, + -- read without interpreting any encoding first. (#9608) + pkgList <- LBS.split 10 <$> getProgramInvocationLBS verbosity (programInvocation pkgConfig ["--list-all"]) -- The output of @pkg-config --list-all@ also includes a description -- for each package, which we do not need. - let pkgNames = map (takeWhile (not . isSpace)) pkgList + let pkgNamesLBS = map (LBS.takeWhile (not . isSpace . chr . fromIntegral)) pkgList + -- Now decode as UTF8 and convert to String, dropping any that fail decoding. + let pkgNames = rights $ map (fmap T.unpack . T.decodeUtf8' . LBS.toStrict) pkgNamesLBS (outs, _errs, exitCode) <- getProgramInvocationOutputAndErrors verbosity (programInvocation pkgConfig ("--modversion" : pkgNames)) From fdd3e243336b47868768f46496b18efe7a8d04cc Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 11:21:42 +0100 Subject: [PATCH 02/15] Add changelog entry --- changelog.d/pr-9609 | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 changelog.d/pr-9609 diff --git a/changelog.d/pr-9609 b/changelog.d/pr-9609 new file mode 100644 index 00000000000..c156706ef03 --- /dev/null +++ b/changelog.d/pr-9609 @@ -0,0 +1,12 @@ +synopsis: Ignore invalid Unicode in pkg-config descriptions +packages: cabal-install-solver +prs: #9609 +issues: #9608 + +description: { + +Previously, cabal-install would crash when `pkg-config --list-all` contained +invalid Unicode. With this change, invalid unicode in package descriptions is +ignored, and unparseable package names are considered nonexistent. + +} From bb9f9da10ea90dbef5768133516d84ca64934b73 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 12:00:29 +0100 Subject: [PATCH 03/15] cabal-install-solver: Add bounds on 'text' --- cabal-install-solver/cabal-install-solver.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index fa8be754ae7..2f1e8d6bdf1 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -110,7 +110,7 @@ library , mtl >=2.0 && <2.4 , pretty ^>=1.1 , transformers >=0.4.2.0 && <0.7 - , text + , text (>= 1.2.3.0 && < 1.3) || (>= 2.0 && < 2.2) if flag(debug-expensive-assertions) cpp-options: -DDEBUG_EXPENSIVE_ASSERTIONS From 6d179f60826619e6d1838391764153e2fce20dbe Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 12:00:46 +0100 Subject: [PATCH 04/15] No literal ASCII values, use 'ord' --- .../src/Distribution/Solver/Types/PkgConfigDb.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 11a67112cf9..a02f1a766c7 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -70,7 +70,8 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do Just (pkgConfig, _) -> do -- To prevent malformed Unicode in the descriptions from crashing cabal, -- read without interpreting any encoding first. (#9608) - pkgList <- LBS.split 10 <$> getProgramInvocationLBS verbosity (programInvocation pkgConfig ["--list-all"]) + pkgList <- LBS.split (fromIntegral (ord '\n')) <$> + getProgramInvocationLBS verbosity (programInvocation pkgConfig ["--list-all"]) -- The output of @pkg-config --list-all@ also includes a description -- for each package, which we do not need. let pkgNamesLBS = map (LBS.takeWhile (not . isSpace . chr . fromIntegral)) pkgList From 6569780cd06e494d9c94316e66377a20057cbac2 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 14:36:32 +0100 Subject: [PATCH 05/15] Address review comments re invalid unicode from pkg-config --- .../Distribution/Solver/Types/PkgConfigDb.hs | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index a02f1a766c7..f3c89404646 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -26,7 +26,6 @@ import Prelude () import Control.Exception (handle) import Control.Monad (mapM) import qualified Data.ByteString.Lazy as LBS -import Data.Either (rights) import qualified Data.Map as M import qualified Data.Text as T import qualified Data.Text.Encoding as T @@ -72,11 +71,30 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do -- read without interpreting any encoding first. (#9608) pkgList <- LBS.split (fromIntegral (ord '\n')) <$> getProgramInvocationLBS verbosity (programInvocation pkgConfig ["--list-all"]) - -- The output of @pkg-config --list-all@ also includes a description - -- for each package, which we do not need. - let pkgNamesLBS = map (LBS.takeWhile (not . isSpace . chr . fromIntegral)) pkgList - -- Now decode as UTF8 and convert to String, dropping any that fail decoding. - let pkgNames = rights $ map (fmap T.unpack . T.decodeUtf8' . LBS.toStrict) pkgNamesLBS + -- Now decode the package *names* to a String. The ones where decoding + -- failed end up in 'failedPkgNames'. + let (failedPkgNames, pkgNames) = + partitionEithers + -- Drop empty package names. This will handle empty lines + -- in pkg-config's output, including the spurious one + -- after the last newline (because of LBS.split). + . filter (either (const True) (not . null)) + -- Try decoding strictly; if it fails, put the lenient + -- decoding in a Left for later reporting. + . map (\bsname -> + let sbsname = LBS.toStrict bsname + in case T.decodeUtf8' sbsname of + Left _ -> Left (T.unpack (T.decodeUtf8Lenient sbsname)) + Right name -> Right (T.unpack name)) + -- The output of @pkg-config --list-all@ also includes a + -- description for each package, which we do not need. + -- We don't use Data.Char.isSpace because that would also + -- include 0xA0, the non-breaking space, which can occur + -- in multi-byte UTF-8 sequences. + . map (LBS.takeWhile (not . isAsciiSpace)) + $ pkgList + when (not (null failedPkgNames)) $ + info verbosity ("Some pkg-config packages have names containing invalid unicode: " ++ intercalate ", " failedPkgNames) (outs, _errs, exitCode) <- getProgramInvocationOutputAndErrors verbosity (programInvocation pkgConfig ("--modversion" : pkgNames)) @@ -114,6 +132,9 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do ExitSuccess -> Just (pkg, pkgVersion) _ -> Nothing + isAsciiSpace :: Word8 -> Bool + isAsciiSpace c = c `elem` map (fromIntegral . ord) " \t" + -- | Create a `PkgConfigDb` from a list of @(packageName, version)@ pairs. pkgConfigDbFromList :: [(String, String)] -> PkgConfigDb pkgConfigDbFromList pairs = (PkgConfigDb . M.fromList . map convert) pairs From 2ec89dcb580083fb9b609554bb8952ac025a6fc9 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 14:35:57 +0100 Subject: [PATCH 06/15] Add test for invalid unicode from pkg-config --- .../PackageTests/PkgConfigParse/MyLibrary.hs | 1 + .../PackageTests/PkgConfigParse/cabal.project | 1 + .../PackageTests/PkgConfigParse/my.cabal | 19 +++++++++ .../PackageTests/PkgConfigParse/pkg-config | 40 +++++++++++++++++++ .../PackageTests/PkgConfigParse/setup.out | 1 + .../PackageTests/PkgConfigParse/setup.test.hs | 9 +++++ 6 files changed, 71 insertions(+) create mode 100644 cabal-testsuite/PackageTests/PkgConfigParse/MyLibrary.hs create mode 100644 cabal-testsuite/PackageTests/PkgConfigParse/cabal.project create mode 100644 cabal-testsuite/PackageTests/PkgConfigParse/my.cabal create mode 100755 cabal-testsuite/PackageTests/PkgConfigParse/pkg-config create mode 100644 cabal-testsuite/PackageTests/PkgConfigParse/setup.out create mode 100644 cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/MyLibrary.hs b/cabal-testsuite/PackageTests/PkgConfigParse/MyLibrary.hs new file mode 100644 index 00000000000..a51c414bcd2 --- /dev/null +++ b/cabal-testsuite/PackageTests/PkgConfigParse/MyLibrary.hs @@ -0,0 +1 @@ +module MyLibrary () where diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/cabal.project b/cabal-testsuite/PackageTests/PkgConfigParse/cabal.project new file mode 100644 index 00000000000..5a93e28e878 --- /dev/null +++ b/cabal-testsuite/PackageTests/PkgConfigParse/cabal.project @@ -0,0 +1 @@ +packages: *.cabal \ No newline at end of file diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/my.cabal b/cabal-testsuite/PackageTests/PkgConfigParse/my.cabal new file mode 100644 index 00000000000..38b7020b8a1 --- /dev/null +++ b/cabal-testsuite/PackageTests/PkgConfigParse/my.cabal @@ -0,0 +1,19 @@ +name: PkgConfigParse +version: 0.1 +license: BSD3 +author: Tom Smeding +maintainer: Tom Smeding +synopsis: Pkg Config Parse +category: PackageTests +build-type: Simple +cabal-version: 2.0 + +description: + Check that Cabal does not crash when pkg-config outputs invalid Unicode. + +Library + pkgconfig-depends: vpl + default-language: Haskell2010 + build-depends: base <5.0 + exposed-modules: + MyLibrary diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config new file mode 100755 index 00000000000..0793e3c933c --- /dev/null +++ b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config @@ -0,0 +1,40 @@ +#!/usr/bin/sh + +set -eu + +# ugly, but "good enough" for this test +# This will need to be updated whenever cabal invokes pkg-config +# in new ways +case "$*" in + '--version') + echo 2.1.0 # whatever + ;; + + '--variable pc_path pkg-config') + echo '.' + ;; + + '--list-all') + printf 'zlib zlib - zlib compression library\n' + # \xAE is the iso-8859-1 (latin-1) encoded version of U+00AE, + # i.e. the "registered sign": ® + # This resulted in problems, see #9608 + printf 'vpl Intel\xAE Video Processing Library - Accelerated video decode, encode, and frame processing capabilities on Intel\xAE GPUs\n' + # \xF0 is latin-1 for ð; this is orð, Icelandic for "word"/"words". + printf 'or\xF0 Icelandic characters\n' + ;; + + '--modversion '*) + shift # drop the --modversion + for arg; do + case "$arg" in + zlib) echo 1.3; ;; # whatever + vpl) echo 2.10; ;; # whatever + # No entry for orð here; let's not even try to match on that + *) + echo >&2 "Package $arg was not found in the pkg-config search path." + exit 1 + esac + done + ;; +esac diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/setup.out b/cabal-testsuite/PackageTests/PkgConfigParse/setup.out new file mode 100644 index 00000000000..92fd8204a40 --- /dev/null +++ b/cabal-testsuite/PackageTests/PkgConfigParse/setup.out @@ -0,0 +1 @@ +# cabal v2-build diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs new file mode 100644 index 00000000000..5f66ef2deb0 --- /dev/null +++ b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs @@ -0,0 +1,9 @@ +import Test.Cabal.Prelude + +-- Test that invalid unicode in pkg-config output doesn't trip up cabal very much +main = cabalTest $ do + -- skipped on windows because using a script to dummy up an executable doesn't work the same. + skipIfWindows + cdir <- testCurrentDir `fmap` getTestEnv + res <- cabal' "v2-build" ["--extra-prog-path="++cdir, "-v2"] + assertOutputContains "Some pkg-config packages have names containing invalid unicode: or?" res From 7d0d59f3ac7dcff4656efddd2318b323b06bc47c Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 16:15:53 +0100 Subject: [PATCH 07/15] Compatibility with text-1.2.5.0 --- .../src/Distribution/Solver/Types/PkgConfigDb.hs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index f3c89404646..14a5aa5a635 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -25,10 +25,12 @@ import Prelude () import Control.Exception (handle) import Control.Monad (mapM) +import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as LBS import qualified Data.Map as M import qualified Data.Text as T import qualified Data.Text.Encoding as T +import qualified Data.Text.Encoding.Error as T import System.FilePath (splitSearchPath) import Distribution.Compat.Environment (lookupEnv) @@ -84,7 +86,7 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do . map (\bsname -> let sbsname = LBS.toStrict bsname in case T.decodeUtf8' sbsname of - Left _ -> Left (T.unpack (T.decodeUtf8Lenient sbsname)) + Left _ -> Left (T.unpack (decodeUtf8LenientCompat sbsname)) Right name -> Right (T.unpack name)) -- The output of @pkg-config --list-all@ also includes a -- description for each package, which we do not need. @@ -135,6 +137,12 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do isAsciiSpace :: Word8 -> Bool isAsciiSpace c = c `elem` map (fromIntegral . ord) " \t" + -- The decodeUtf8Lenient function is defined starting with text-2.0.1; this + -- function simply reimplements it. When the minimum supported GHC version + -- is >= 9.4, switch to decodeUtf8Lenient. + decodeUtf8LenientCompat :: ByteString -> T.Text + decodeUtf8LenientCompat = T.decodeUtf8With T.lenientDecode + -- | Create a `PkgConfigDb` from a list of @(packageName, version)@ pairs. pkgConfigDbFromList :: [(String, String)] -> PkgConfigDb pkgConfigDbFromList pairs = (PkgConfigDb . M.fromList . map convert) pairs From e724111d0d9896a1af5127d1c4ae57a800cfe2b0 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 11 Jan 2024 17:01:49 +0100 Subject: [PATCH 08/15] Align imports --- .../src/Distribution/Solver/Types/PkgConfigDb.hs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 14a5aa5a635..75fc43b203c 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -23,15 +23,15 @@ module Distribution.Solver.Types.PkgConfigDb import Distribution.Solver.Compat.Prelude import Prelude () -import Control.Exception (handle) -import Control.Monad (mapM) -import Data.ByteString (ByteString) -import qualified Data.ByteString.Lazy as LBS -import qualified Data.Map as M -import qualified Data.Text as T -import qualified Data.Text.Encoding as T +import Control.Exception (handle) +import Control.Monad (mapM) +import Data.ByteString (ByteString) +import qualified Data.ByteString.Lazy as LBS +import qualified Data.Map as M +import qualified Data.Text as T +import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding.Error as T -import System.FilePath (splitSearchPath) +import System.FilePath (splitSearchPath) import Distribution.Compat.Environment (lookupEnv) import Distribution.Package (PkgconfigName, mkPkgconfigName) From 2900ecd5b3f0a02dccbe043c4e4454706fa4e58a Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Fri, 12 Jan 2024 13:03:27 +0100 Subject: [PATCH 09/15] Handle different exception type --- .../src/Distribution/Solver/Types/PkgConfigDb.hs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 75fc43b203c..b14491309c4 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -1,5 +1,6 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE LambdaCase #-} ----------------------------------------------------------------------------- -- | -- Module : Distribution.Solver.Types.PkgConfigDb @@ -23,7 +24,7 @@ module Distribution.Solver.Types.PkgConfigDb import Distribution.Solver.Compat.Prelude import Prelude () -import Control.Exception (handle) +import Control.Exception (handle, handleJust) import Control.Monad (mapM) import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as LBS @@ -36,11 +37,12 @@ import System.FilePath (splitSearchPath) import Distribution.Compat.Environment (lookupEnv) import Distribution.Package (PkgconfigName, mkPkgconfigName) import Distribution.Parsec +import Distribution.Simple.Errors (CabalException(..)) import Distribution.Simple.Program (ProgramDb, getProgramOutput, pkgConfigProgram, needProgram, ConfiguredProgram) import Distribution.Simple.Program.Run (getProgramInvocationOutputAndErrors, programInvocation, getProgramInvocationLBS) -import Distribution.Simple.Utils (info) +import Distribution.Simple.Utils (info, VerboseException(..)) import Distribution.Types.PkgconfigVersion import Distribution.Types.PkgconfigVersionRange import Distribution.Verbosity (Verbosity) @@ -72,7 +74,11 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do -- To prevent malformed Unicode in the descriptions from crashing cabal, -- read without interpreting any encoding first. (#9608) pkgList <- LBS.split (fromIntegral (ord '\n')) <$> - getProgramInvocationLBS verbosity (programInvocation pkgConfig ["--list-all"]) + handleJust + (\case e@(VerboseException _ _ _ GetProgramInvocationLBSException{}) -> Just e + _ -> Nothing) + (ioError . userError . show) + (getProgramInvocationLBS verbosity (programInvocation pkgConfig ["--list-all"])) -- Now decode the package *names* to a String. The ones where decoding -- failed end up in 'failedPkgNames'. let (failedPkgNames, pkgNames) = From 89a2f054493eadb505f752d46aad89aef08e8c96 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Tue, 23 Jan 2024 21:36:26 +0100 Subject: [PATCH 10/15] Use only POSIX shell syntax --- cabal-testsuite/PackageTests/PkgConfigParse/pkg-config | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config index 0793e3c933c..1db8b37a117 100755 --- a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config +++ b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config @@ -16,12 +16,12 @@ case "$*" in '--list-all') printf 'zlib zlib - zlib compression library\n' - # \xAE is the iso-8859-1 (latin-1) encoded version of U+00AE, + # \256 = \xAE is the iso-8859-1 (latin-1) encoded version of U+00AE, # i.e. the "registered sign": ® # This resulted in problems, see #9608 - printf 'vpl Intel\xAE Video Processing Library - Accelerated video decode, encode, and frame processing capabilities on Intel\xAE GPUs\n' - # \xF0 is latin-1 for ð; this is orð, Icelandic for "word"/"words". - printf 'or\xF0 Icelandic characters\n' + printf 'vpl Intel\256 Video Processing Library - Accelerated video decode, encode, and frame processing capabilities on Intel\256 GPUs\n' + # \360 = \xF0 is latin-1 for ð; this is orð, Icelandic for "word"/"words". + printf 'or\360 Icelandic characters\n' ;; '--modversion '*) From 28f7082bc19834b1c24bffd8752c8dec6aaa167b Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Tue, 23 Jan 2024 21:39:49 +0100 Subject: [PATCH 11/15] Add invalid-input handler in pkg-config shim This is to appease shellcheck --- cabal-testsuite/PackageTests/PkgConfigParse/pkg-config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config index 1db8b37a117..de30568d65a 100755 --- a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config +++ b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config @@ -37,4 +37,9 @@ case "$*" in esac done ;; + + *) + echo >&2 "pkg-config: unrecognised arguments (this is an incomplete shim)" + exit 1 + ;; esac From ab8870a4213c46c8908b1af2a5bd502c6c16672c Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Tue, 23 Jan 2024 21:42:36 +0100 Subject: [PATCH 12/15] Actually implement all required stuff in the pkg-config shim --- cabal-testsuite/PackageTests/PkgConfigParse/pkg-config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config index de30568d65a..0f1e9283f38 100755 --- a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config +++ b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config @@ -38,8 +38,12 @@ case "$*" in done ;; + # Ignore some stuff we're not implementing + '--cflags '*) ;; + '--libs '*) ;; + *) - echo >&2 "pkg-config: unrecognised arguments (this is an incomplete shim)" + echo >&2 "pkg-config: unrecognised arguments $* (this is an incomplete shim)" exit 1 ;; esac From 8057eb3dbd01f422620e9db192966fa72cee0d99 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Tue, 23 Jan 2024 22:52:14 +0100 Subject: [PATCH 13/15] Less exception dance --- Cabal/src/Distribution/Simple/Program/Run.hs | 8 ++++++++ .../Distribution/Solver/Types/PkgConfigDb.hs | 18 ++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Cabal/src/Distribution/Simple/Program/Run.hs b/Cabal/src/Distribution/Simple/Program/Run.hs index 27ff33dce01..ec4b3cc556e 100644 --- a/Cabal/src/Distribution/Simple/Program/Run.hs +++ b/Cabal/src/Distribution/Simple/Program/Run.hs @@ -24,6 +24,7 @@ module Distribution.Simple.Program.Run , getProgramInvocationOutput , getProgramInvocationLBS , getProgramInvocationOutputAndErrors + , getProgramInvocationLBSAndErrors , getEffectiveEnvironment ) where @@ -190,6 +191,13 @@ getProgramInvocationOutputAndErrors verbosity inv = case progInvokeOutputEncodin (output', errors, exitCode) <- getProgramInvocationIODataAndErrors verbosity inv IODataModeBinary return (normaliseLineEndings (fromUTF8LBS output'), errors, exitCode) +getProgramInvocationLBSAndErrors + :: Verbosity + -> ProgramInvocation + -> IO (LBS.ByteString, String, ExitCode) +getProgramInvocationLBSAndErrors verbosity inv = + getProgramInvocationIODataAndErrors verbosity inv IODataModeBinary + getProgramInvocationIODataAndErrors :: KnownIODataMode mode => Verbosity diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index b14491309c4..21845eafdec 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -24,7 +24,7 @@ module Distribution.Solver.Types.PkgConfigDb import Distribution.Solver.Compat.Prelude import Prelude () -import Control.Exception (handle, handleJust) +import Control.Exception (handle) import Control.Monad (mapM) import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as LBS @@ -37,12 +37,11 @@ import System.FilePath (splitSearchPath) import Distribution.Compat.Environment (lookupEnv) import Distribution.Package (PkgconfigName, mkPkgconfigName) import Distribution.Parsec -import Distribution.Simple.Errors (CabalException(..)) import Distribution.Simple.Program (ProgramDb, getProgramOutput, pkgConfigProgram, needProgram, ConfiguredProgram) import Distribution.Simple.Program.Run - (getProgramInvocationOutputAndErrors, programInvocation, getProgramInvocationLBS) -import Distribution.Simple.Utils (info, VerboseException(..)) + (getProgramInvocationOutputAndErrors, programInvocation, getProgramInvocationLBSAndErrors) +import Distribution.Simple.Utils (info) import Distribution.Types.PkgconfigVersion import Distribution.Types.PkgconfigVersionRange import Distribution.Verbosity (Verbosity) @@ -73,12 +72,11 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do Just (pkgConfig, _) -> do -- To prevent malformed Unicode in the descriptions from crashing cabal, -- read without interpreting any encoding first. (#9608) - pkgList <- LBS.split (fromIntegral (ord '\n')) <$> - handleJust - (\case e@(VerboseException _ _ _ GetProgramInvocationLBSException{}) -> Just e - _ -> Nothing) - (ioError . userError . show) - (getProgramInvocationLBS verbosity (programInvocation pkgConfig ["--list-all"])) + (listAllOutput, listAllErrs, listAllExitcode) <- + getProgramInvocationLBSAndErrors verbosity (programInvocation pkgConfig ["--list-all"]) + when (listAllExitcode /= ExitSuccess) $ + ioError (userError ("pkg-config --list-all failed: " ++ listAllErrs)) + let pkgList = LBS.split (fromIntegral (ord '\n')) listAllOutput -- Now decode the package *names* to a String. The ones where decoding -- failed end up in 'failedPkgNames'. let (failedPkgNames, pkgNames) = From fd66f0cb40575bec7e82957fc0f9760edd0bf849 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 24 Jan 2024 21:42:14 +0100 Subject: [PATCH 14/15] Fix shebang lines MacOS doesn't have /usr/bin/sh, and /bin/sh is the standard (for a POSIX shell) anyway --- cabal-testsuite/PackageTests/ExtraProgPath/pkg-config | 2 +- cabal-testsuite/PackageTests/PkgConfigParse/pkg-config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal-testsuite/PackageTests/ExtraProgPath/pkg-config b/cabal-testsuite/PackageTests/ExtraProgPath/pkg-config index 7c5fafbf0ca..195df7c2c41 100755 --- a/cabal-testsuite/PackageTests/ExtraProgPath/pkg-config +++ b/cabal-testsuite/PackageTests/ExtraProgPath/pkg-config @@ -1,3 +1,3 @@ -#!/usr/bin/sh +#!/bin/sh exit 1; diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config index 0f1e9283f38..183d08e0a00 100755 --- a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config +++ b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config @@ -1,4 +1,4 @@ -#!/usr/bin/sh +#!/bin/sh set -eu From 16b2fc8e8bd58324ba1eff74dae0e9f9121f0f7f Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 25 Jan 2024 00:02:58 +0100 Subject: [PATCH 15/15] Don't expect a particular representation of invalid characters --- cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs index 5f66ef2deb0..0f860ab637a 100644 --- a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs +++ b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs @@ -6,4 +6,4 @@ main = cabalTest $ do skipIfWindows cdir <- testCurrentDir `fmap` getTestEnv res <- cabal' "v2-build" ["--extra-prog-path="++cdir, "-v2"] - assertOutputContains "Some pkg-config packages have names containing invalid unicode: or?" res + assertOutputContains "Some pkg-config packages have names containing invalid unicode: or" res