Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that FilePaths don't contain interior NULs #218

Merged
merged 1 commit into from
Dec 16, 2023

Conversation

hasufell
Copy link
Member

Follows:


Another possible implementation is to simply switch out withTString and make it fail on any NUL char. But I'm not sure that's what we want to do. I don't have a clear picture what other APIs this can affect, but it's clear we don't want this behavior when it's about filepaths, so we specialize here.

@@ -189,6 +190,9 @@ newTString :: String -> IO LPCTSTR
-- UTF-16 version:
type TCHAR = CWchar
withTString = withCWString
withFilePath path f = do
checkForInteriorNuls path
withCWString path f
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

withCWString has the following definition:

withCWString :: String -> (CWString -> IO a) -> IO a
withCWString  = withArray0 wNUL . charsToCWchars

charsToCWchars :: [Char] -> [CWchar]
charsToCWchars = foldr utf16Char [] . map ord
 where
  utf16Char c wcs
    | c < 0x10000 = fromIntegral c : wcs
    | otherwise   = let c' = c - 0x10000 in
                    fromIntegral (c' `div` 0x400 + 0xd800) :
                    fromIntegral (c' `mod` 0x400 + 0xdc00) : wcs

Which I think is safe from introducing additional NUL bytes during decoding.

@hasufell
Copy link
Member Author

Are there any other modules dealing with filepath primitives?

@@ -203,6 +207,21 @@ peekTStringLen = peekCStringLen
newTString = newCString
-}

-- | Check a 'FilePath' for internal NUL codepoints as these are
-- disallowed in Windows filepaths. See #13660.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which 13660 is this? GHC?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mistuke
Copy link
Contributor

Mistuke commented Mar 25, 2023

Are there any other modules dealing with filepath primitives?

Not that I know off, I do intend to replace the entire library at some point with autogenerated ones so we'll have more then.

Thanks for the submission. Could you just update the comment to say it's a GHC #13660 and add a changelog entry. I assume this is urgent? I will make the release later tonight.

@Mistuke
Copy link
Contributor

Mistuke commented Mar 25, 2023

Note that process's APIs can also take FilePaths, the arguments to CreateProcess both accept full paths. So I suppose it might be worth adding a check to commandToProcess there

@hasufell
Copy link
Member Author

I assume this is urgent? I will make the release later tonight.

Not urgent. The CLC still hasn't voted on it. It just needs to be released in lockstep with the base version containing the fix.

@hasufell
Copy link
Member Author

Ping

@Mistuke
Copy link
Contributor

Mistuke commented Dec 15, 2023

Ah I was waiting until the CLC vote. I assume that's happened now? If so would you mind rebasing?

@hasufell
Copy link
Member Author

The CLC vote passed: haskell/core-libraries-committee#144 (comment)

I can rebase later, I'm out for dinner.

Comment on lines +120 to +126
let len = SBS.numWord16 path
clen <- c_wcslen ptr
if clen == fromIntegral len
then f ptr
else do
path' <- either (const (_toStr wp)) id <$> (EX.try @IOException) (decodeWithBaseWindows path)
ioError (err path')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little more efficient than the String variant and we do the same in unix package.

System/Win32/Types.hsc Outdated Show resolved Hide resolved
@hasufell
Copy link
Member Author

All done

@Mistuke Mistuke merged commit 6794327 into haskell:master Dec 16, 2023
0 of 3 checks passed
@Mistuke
Copy link
Contributor

Mistuke commented Dec 16, 2023

Thanks!

@hasufell
Copy link
Member Author

Will you make a release?

@Mistuke
Copy link
Contributor

Mistuke commented Dec 16, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants