_markupbase.py if not match: UnboundLocalError: local variable 'match' referenced before assignment,分析Python 库 html.parser 中存在的一个解析BUG
BUG触发时的完整报错内容(本地无关路径用已经用 **** 隐去):
**************\lib\site-packages\bs4\builder\_htmlparser.py:78: UserWarning: unknown status keyword 'end ' in marked section
warnings.warn(msg)
Traceback (most recent call last):
File "**************/test.py", line 5, in <module>
bs = BeautifulSoup(html, 'html.parser')
File "**************\lib\site-packages\bs4\__init__.py", line 281, in __init__
self._feed()
File "**************\lib\site-packages\bs4\__init__.py", line 342, in _feed
self.builder.feed(self.markup)
File "**************\lib\site-packages\bs4\builder\_htmlparser.py", line 247, in feed
parser.feed(markup)
File "D:\Program Files\Python37\lib\html\parser.py", line 111, in feed
self.goahead(0)
File "D:\Program Files\Python37\lib\html\parser.py", line 179, in goahead
k = self.parse_html_declaration(i)
File "D:\Program Files\Python37\lib\html\parser.py", line 264, in parse_html_declaration
return self.parse_marked_section(i)
File "D:\Program Files\Python37\lib\_markupbase.py", line 160, in parse_marked_section
if not match:
UnboundLocalError: local variable 'match' referenced before assignment
在解析HTML时,标签开始部分使用形如 <!-[if IE eq 9]>
的浏览器判断标识符,结束时结束标签<![end if]->
(正确的开始和结束标签应该为<!--[if IE 9]>
和 <![endif]-->
)无法正常匹配关闭即可触发。
触发BUG的示例代码如下:
from bs4 import BeautifulSoup
html = """
<!-[if IE eq 9]>
<a href="https://www.shwww.net/">https://www.shwww.net/</a>
<![end if]->
"""
bs = BeautifulSoup(html, 'html.parser')
在 Python 3.7.0 版本中,触发BUG部分的代码存在于 \Lib\_markupbase.py
中的 146 行的 parse_marked_section
方法,该方法代码如下:
https://github.com/python/cpython/blob/bb9ddee3d4e293f0717f8c167afdf5749ebf843d/Lib/_markupbase.py#L160
def parse_marked_section(self, i, report=1):
rawdata= self.rawdata
assert rawdata[i:i+3] == '<![', "unexpected call to parse_marked_section()"
sectName, j = self._scan_name( i+3, i )
if j < 0:
return j
if sectName in {"temp", "cdata", "ignore", "include", "rcdata"}:
# look for standard ]]> ending
match= _markedsectionclose.search(rawdata, i+3)
elif sectName in {"if", "else", "endif"}:
# look for MS Office ]> ending
match= _msmarkedsectionclose.search(rawdata, i+3)
else:
self.error('unknown status keyword %r in marked section' % rawdata[i+3:j])
if not match:
return -1
if report:
j = match.start(0)
self.unknown_decl(rawdata[i+3: j])
return match.end(0)
由于错误的HTML代码未正确关闭,使得流程判断既没有进入 if sectName in {"temp", "cdata", "ignore", "include", "rcdata"}:
和 elif sectName in {"if", "else", "endif"}:
,而是报出一个错误 UserWarning: unknown status keyword 'end ' in marked section warnings.warn(msg)
后执行到 if not match
,而此时 match
未申明,故而触发错误。
此BUG存在于多个Python版本中,修复方法,在 if sectName in {"temp", "cdata", "ignore", "include", "rcdata"}:
之前预定义一个match变量即可:
https://github.com/python/cpython/blob/bb9ddee3d4e293f0717f8c167afdf5749ebf843d/Lib/_markupbase.py#L152
def parse_marked_section(self, i, report=1):
rawdata= self.rawdata
assert rawdata[i:i+3] == '<![', "unexpected call to parse_marked_section()"
sectName, j = self._scan_name( i+3, i )
if j < 0:
return j
match = None
if sectName in {"temp", "cdata", "ignore", "include", "rcdata"}:
# look for standard ]]> ending
match= _markedsectionclose.search(rawdata, i+3)
elif sectName in {"if", "else", "endif"}:
# look for MS Office ]> ending
match= _msmarkedsectionclose.search(rawdata, i+3)
else:
self.error('unknown status keyword %r in marked section' % rawdata[i+3:j])
if not match:
return -1
if report:
j = match.start(0)
self.unknown_decl(rawdata[i+3: j])
return match.end(0)
_markupbase.py if not match: UnboundLocalError: local variable 'match' referenced before assignment,分析Python 库 html.parser 中存在的一个解析BUG的更多相关文章
- RDO Stack Exception: UnboundLocalError: local variable 'logFile' referenced before assignment
Issue: When you install RDO stack on CentOS, you may encounter following error. Error: [root@localho ...
- UnboundLocalError: local variable 'range' referenced before assignment
1. 报错信息 UnboundLocalError: local variable 'range' referenced before assignment 2. 代码 class Car(): &q ...
- 洗礼灵魂,修炼python(23)--自定义函数(4)—闭包进阶问题—>报错UnboundLocalError: local variable 'x' referenced before assignment
闭包(lexical closure) 什么是闭包前面已经说过了,但是由于遗留问题,所以单独作为一个章节详解讲解下 不多说,看例子: def funx(x): def funy(y): return ...
- 变量引用的错误:UnboundLocalError: local variable 'range' referenced before assignment
class Battery(): """一次模拟电瓶汽车的简单尝试""" def __init__(self,battery_size = ...
- 出现UnboundLocalError: local variable 'a' referenced before assignment异常的情况与解决方法
出现UnboundLocalError: local variable ‘a’ referenced before assignment异常的情况与解决方法字面意思:局部变量赋值前被引用原因:局部变量 ...
- 全局变量报错:UnboundLocalError: local variable 'l' referenced before assignment
总结: 内部函数,不修改全局变量可以访问全局变量 内部函数,修改同名全局变量,则python会认为它是一个局部变量 在内部函数修改同名全局变量之前调用变量名称(如print sum),则引发Unbou ...
- python:UnboundLocalError: local variable 'xxx' referenced before assignment
近来一直都在学习python语言,偶然在伯乐在线看到2017年京东C/C++的面试题.就打算用python+ST3 IDE顺便敲下面试题代码. 原题 C语言: #include <stdio.h ...
- UnboundLocalError: local variable ‘xxx‘ referenced before assignment
原因 在Python函数中调用了某个和全局变量同名的局部变量,导致编译器不知道此时使用的是全局变量还是局部变量 a = 3 def func(): a+=3 func() UnboundLocalEr ...
- UnboundLocalError: local variable 'f' referenced before assignment
参考方案链接: 1.http://blog.chinaunix.net/uid-631981-id-3766212.html 2.http://blog.sina.com.cn/s/blog_4b9e ...
随机推荐
- hdu 1050 Moving Tables(迷之贪心...)
题意:有400间房间按题目中图片所给的方式排列,然后给出要移动的n张桌子所要移动的范围,每张桌子要移动的范围不能出现重叠的区域:问最少要多少次才能移动完所有的桌子. 题解思路:把题目转换下,就是有n个 ...
- iOS UITableView 去除多余切割线
在UITableView初始化时加上下面代码就可以: self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero ...
- ListView无障碍识别整个listView,不识别item,设置了setContentDescription也没实用
点击ListView的时候.无障碍识别到的是整个listView,不会读点击的那个item. 解决的方法是在getView里手动设置: <span style="font-size:1 ...
- luogu3225 [HNOI2012]矿场搭建
题目大意 给出一个有$n(n\leq 500)$个节点的无向图,一个满足条件的点集$V$会使得对于图中的每一个节点$u$,满足路径起点为$u$终点$v\in V$的路径集合$P_u$中总存在至少两条路 ...
- hdoj--1418--抱歉(水题)
抱歉 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- Oracle_exp/expdp备份
目录索引 1.exp和expdp的区别 2.expdp导出数据库流程 一.↓↓exp和expdp的区别↓↓ 1.exp和expdp最明显的区别就是导出速度的不同.expdp导出是并行导出(如果把exp ...
- gdb打印vector
1.gdb版本大于7.0 (gdb) p yourVector 2.打印整个vector (gdb) p *(yourVector._M_impl._M_start)@yourVector.size( ...
- Halcon学习笔记之支持向量机(二)
例程:classify_halogen_bulbs.hdev 在Halcon中模式匹配最成熟最常用的方式该署支持向量机了,在本例程中展示了使用支持向量机对卤素灯的质量检测方法.通过这个案例,相信大家可 ...
- IO流遍历文件夹下所有文件问题
import java.io.File; /** * @author 王恒 * @datetime 2017年4月20日 下午2:24:32 * @description 递归调用 * */ publ ...
- Spring Boot (13) druid监控
druid druid是和tomcat jdbc一样优秀的连接池,出自阿里巴巴.除了连接池,druid哈hi有一个很实用的监控功能. pom.xml 添加了以下依赖后,会自动用druid连接池替代默认 ...