diff --git a/cssselect/xpath.py b/cssselect/xpath.py index a8722bb..0c4daa5 100644 --- a/cssselect/xpath.py +++ b/cssselect/xpath.py @@ -326,6 +326,12 @@ def xpath_class(self, class_selector): def xpath_hash(self, id_selector): """Translate an ID selector.""" xpath = self.xpath(id_selector.selector) + is_valid_identifier = not (re.match('--', id_selector.id) + or re.match('[0-9]', id_selector.id) + or re.match('-[0-9]', id_selector.id) + ) + if not is_valid_identifier: + raise ExpressionError("invalid identifier") return self.xpath_attrib_equals(xpath, '@id', id_selector.id) def xpath_element(self, selector): diff --git a/tests/test_cssselect.py b/tests/test_cssselect.py index d6969f2..349a8d4 100644 --- a/tests/test_cssselect.py +++ b/tests/test_cssselect.py @@ -526,6 +526,9 @@ def xpath(css): self.assertRaises(ExpressionError, xpath, ':lorem-ipsum') self.assertRaises(ExpressionError, xpath, ':lorem(ipsum)') self.assertRaises(ExpressionError, xpath, '::lorem-ipsum') + self.assertRaises(ExpressionError, xpath, '#00FF55') + self.assertRaises(ExpressionError, xpath, '#--abc') + self.assertRaises(ExpressionError, xpath, '#-1abc') self.assertRaises(TypeError, GenericTranslator().css_to_xpath, 4) self.assertRaises(TypeError, GenericTranslator().selector_to_xpath, 'foo')