Skip to content

Commit 64af697

Browse files
committed
Properly catch when missing close parenthesis and raise XPathParseError. With test.
1 parent ecff37f commit 64af697

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

AdvancedHTMLParser/xpath/_body.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,8 @@ def _parseBodyLevelGroup(restOfBody):
20552055
curString = restOfBody[:].strip()
20562056
ret = []
20572057

2058+
foundCloseParen = False
2059+
20582060
while curString:
20592061

20602062
gotMatch = False
@@ -2068,6 +2070,8 @@ def _parseBodyLevelGroup(restOfBody):
20682070
newCurString = curString[ groupCloseMatch.span()[1] : ]
20692071
curString = newCurString
20702072

2073+
foundCloseParen = True
2074+
20712075
break
20722076

20732077
groupOpenMatch = bodyElementGroupOpenRE.match(curString)
@@ -2101,6 +2105,9 @@ def _parseBodyLevelGroup(restOfBody):
21012105

21022106
curString = newCurString
21032107

2108+
if foundCloseParen is False:
2109+
2110+
raise XPathParseError('Missing close parenthesis for section: "%s"' %(restOfBody, ))
21042111

21052112

21062113
# Optimization: Before returning, run through and perform any operations against static values possible
@@ -2137,6 +2144,8 @@ def _parseFunctionArgsToBodyElements(restOfBody):
21372144
fnArgs = []
21382145
curGroupElements = []
21392146

2147+
foundCloseParen = False
2148+
21402149
while curString:
21412150

21422151
gotMatch = False
@@ -2150,6 +2159,8 @@ def _parseFunctionArgsToBodyElements(restOfBody):
21502159
newCurString = curString[ groupCloseMatch.span()[1] : ]
21512160
curString = newCurString
21522161

2162+
foundCloseParen = True
2163+
21532164
break
21542165

21552166
nextArgMatch = bodyElementGroupFunctionNextArgRE.match(curString)
@@ -2218,6 +2229,9 @@ def _parseFunctionArgsToBodyElements(restOfBody):
22182229

22192230
curString = newCurString
22202231

2232+
if foundCloseParen is False:
2233+
2234+
raise XPathParseError('Missing close parenthesis for section: "%s"' %(restOfBody, ))
22212235

22222236
if len(curGroupElements) > 0:
22232237
# Optimize the group elements

tests/AdvancedHTMLParserTests/test_XPath.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import AdvancedHTMLParser
1111

1212
from AdvancedHTMLParser.xpath._body import parseBodyStringIntoBodyElements, BodyElementValue, BodyElementValue_Boolean
13+
from AdvancedHTMLParser.xpath.exceptions import XPathParseError
1314

1415
class TestXPath(object):
1516
'''
@@ -493,6 +494,30 @@ def test_xpathCache(self):
493494

494495
assert timeWithCache < timeWithoutCache , 'Expected compiling XPath strings to be faster when caching the compiled result, but was not.\nTime with cache : %.7f\nTime without cache: %.7f' %( timeWithCache, timeWithoutCache)
495496

497+
498+
def test_xpathCatchMissingCloseParen(self):
499+
'''
500+
test_xpathCatchMissingCloseParen - Test that we properly catch missing close parenthesis
501+
'''
502+
try:
503+
shouldWork = self.parser.getElementsByXPathExpression('//span[ (@name = ("itemName") ) ]')
504+
except Exception as exc:
505+
raise AssertionError('Expected normal parenthesis to parse correctly, but got exception: %s %s' %( exc.__class__.__name__, str(exc) ))
506+
507+
508+
didWork = True
509+
theException = None
510+
try:
511+
shouldNotWork = self.parser.getElementsByXPathExpression('//span[ (@name = ("itemName" ) ]')
512+
except XPathParseError as exc2:
513+
didWork = False
514+
theException = exc2
515+
516+
assert didWork is False , 'Expected missing parenthesis to properly raise an XPathParseError exception, but it did not!'
517+
518+
assert 'Missing close' in str(theException) , 'Expected "Missing close" to be in the XPathParseError message for missing parenthesis, but it was not! Exception message was: %s' %(str(theException), )
519+
520+
496521
if __name__ == '__main__':
497522
sys.exit(subprocess.Popen('GoodTests.py -n1 "%s" %s' %(sys.argv[0], ' '.join(['"%s"' %(arg.replace('"', '\\"'), ) for arg in sys.argv[1:]]) ), shell=True).wait())
498523

0 commit comments

Comments
 (0)