Skip to content
This repository has been archived by the owner on Apr 1, 2022. It is now read-only.

Requirements.txt: fix hang when parsing unsupported fields #235

Merged
merged 2 commits into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Unreleased
zlav marked this conversation as resolved.
Show resolved Hide resolved

- Requirements.txt: fix hang when parsing unsupported fields ([#235](https://github.com/fossas/spectrometer/pull/235))

# v2.5.14

- Golang: map package imports to modules ([#234](https://github.com/fossas/spectrometer/pull/234))
Expand Down
10 changes: 3 additions & 7 deletions src/Strategy/Python/ReqTxt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,18 @@ reqParser = [] <$ char '-' <* ignored -- pip options
<|> [] <$ char '/' <* ignored -- absolute path
<|> [] <$ oneOfS ["http:", "https:", "git+", "hg+", "svn+", "bzr+"] <* ignored -- URLs
<|> [] <$ comment
<|> (pure <$> requirementParser <* ignored)
<|> pure [] -- empty line
<|> (pure <$> try requirementParser <* ignored)
<|> [] <$ ignored -- something else we're not able to parse

where
isEndLine :: Char -> Bool
isEndLine '\n' = True
isEndLine '\r' = True
isEndLine '\\' = True
isEndLine _ = False

-- ignore content until the end of the line
ignored :: Parser ()
ignored = () <$ takeWhileP (Just "ignored") (not . isEndLine) <* (try newLine <|> (() <$ takeWhileP (Just "end of line") isEndLine))

newLine :: Parser ()
Copy link
Member

Choose a reason for hiding this comment

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

I'm curious if removing this newLine parsing will ever come back to bite us, although I don't see any difference between the way I implemented it and the way you are handling it. If we ever want to capture the data in the newlines, such as hash like in the test file, this may come in handy, but until then I don't care.

newLine = char '\\' <* takeWhileP (Just "endLine") isEndLine *> ignored
ignored = () <$ takeWhileP (Just "ignored") (not . isEndLine) <* takeWhileP (Just "end of line") isEndLine

comment :: Parser ()
comment = char '#' *> ignored
Expand Down
2 changes: 1 addition & 1 deletion test/Python/RequirementsSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ spec = do
T.it "can parse" $
case runParser requirementsTxtParser "" requirementsTextFile of
Left r -> do
T.expectationFailure $ "failed to parse: error:" ++ show r
T.expectationFailure $ "failed to parse: error:" ++ errorBundlePretty r
Right res -> do
let result = buildGraph res
expectDeps [depOne, depTwo, depThree, depFour] result
3 changes: 2 additions & 1 deletion test/Python/testdata/req.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ three==3.0.0 \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
# via python-dateuti
four==4.0.0 #help
[foo]
four==4.0.0 #help