Skip to content

Commit f1042ec

Browse files
committed
gh-153404: Silently ignore non-decimal digits in robots.txt Crawl-delay and Request-rate
str.isdigit() returns True for non-decimal Unicode digits such as U+00B2 SUPERSCRIPT TWO, which int() then rejects with ValueError. In RobotFileParser.parse() this raised a raw ValueError that aborted parsing of the entire robots.txt file, unlike every other malformed directive which is silently ignored. Guard the Crawl-delay and Request-rate conversions with str.isdecimal() so a value written with non-decimal digits is ignored instead of raising.
1 parent f3fd9dc commit f1042ec

3 files changed

Lines changed: 29 additions & 3 deletions

File tree

Lib/test/test_robotparser.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,28 @@ class InvalidCrawlDelayTest(BaseRobotTest, unittest.TestCase):
246246
bad = []
247247

248248

249+
class NonDecimalCrawlDelayTest(BaseRequestRateTest, unittest.TestCase):
250+
# Non-decimal Unicode digits pass str.isdigit() but int() rejects
251+
# them, so the directive must be silently ignored, not raise.
252+
robots_txt = """\
253+
User-Agent: *
254+
Disallow: /.
255+
Crawl-delay: ²
256+
"""
257+
good = ['/foo.html']
258+
bad = []
259+
260+
261+
class NonDecimalRequestRateTest(BaseRequestRateTest, unittest.TestCase):
262+
robots_txt = """\
263+
User-agent: *
264+
Disallow: /tmp/
265+
Request-rate: ²/5
266+
"""
267+
good = ['/foo.html']
268+
bad = ['/tmp/']
269+
270+
249271
class AnotherInvalidRequestRateTest(BaseRobotTest, unittest.TestCase):
250272
# also test that Allow and Diasallow works well with each other
251273
robots_txt = """\

Lib/urllib/robotparser.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,15 @@ def parse(self, lines):
148148
# before trying to convert to int we need to make
149149
# sure that robots.txt has valid syntax otherwise
150150
# it will crash
151-
if line[1].strip().isdigit():
151+
if line[1].strip().isdecimal():
152152
entry.delay = int(line[1])
153153
state = 2
154154
elif line[0] == "request-rate":
155155
if state != 0:
156156
numbers = line[1].split('/')
157157
# check if all values are sane
158-
if (len(numbers) == 2 and numbers[0].strip().isdigit()
159-
and numbers[1].strip().isdigit()):
158+
if (len(numbers) == 2 and numbers[0].strip().isdecimal()
159+
and numbers[1].strip().isdecimal()):
160160
entry.req_rate = RequestRate(int(numbers[0]), int(numbers[1]))
161161
state = 2
162162
elif line[0] == "sitemap":
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:class:`urllib.robotparser.RobotFileParser` now silently ignores a
2+
``Crawl-delay`` or ``Request-rate`` value written with non-decimal digits
3+
(such as ``U+00B2 SUPERSCRIPT TWO``) instead of raising :exc:`ValueError`
4+
and aborting the parse of the whole ``robots.txt`` file.

0 commit comments

Comments
 (0)