同步操作将从 yeqingchen1/sqlmap 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
"""A parser for SGML, using the derived class as a static DTD."""# Note: missing in Python3# XXX This only supports those SGML features used by HTML.# XXX There should be a way to distinguish between PCDATA (parsed# character data -- the normal case), RCDATA (replaceable character# data -- only char and entity references and end tags are special)# and CDATA (character data -- only end tags are special). RCDATA is# not supported at all.from __future__ import print_functiontry:import _markupbase as markupbaseexcept:import markupbaseimport re__all__ = ["SGMLParser", "SGMLParseError"]# Regular expressions used for parsinginteresting = re.compile('[&<]')incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|''<([a-zA-Z][^<>]*|''/([a-zA-Z][^<>]*)?|''![^<>]*)?')entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')charref = re.compile('&#([0-9]+)[^0-9]')starttagopen = re.compile('<[>a-zA-Z]')shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')piclose = re.compile('>')endbracket = re.compile('[<>]')tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')attrfind = re.compile(r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?')class SGMLParseError(RuntimeError):"""Exception raised for all parse errors."""pass# SGML parser base class -- find tags and call handler functions.# Usage: p = SGMLParser(); p.feed(data); ...; p.close().# The dtd is defined by deriving a class which defines methods# with special names to handle tags: start_foo and end_foo to handle# <foo> and </foo>, respectively, or do_foo to handle <foo> by itself.# (Tags are converted to lower case for this purpose.) The data# between tags is passed to the parser by calling self.handle_data()# with some data as argument (the data may be split up in arbitrary# chunks). Entity references are passed by calling# self.handle_entityref() with the entity reference as argument.class SGMLParser(markupbase.ParserBase):# Definition of entities -- derived classes may overrideentity_or_charref = re.compile('&(?:''([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)'')(;?)')def __init__(self, verbose=0):"""Initialize and reset this instance."""self.verbose = verboseself.reset()def reset(self):"""Reset this instance. Loses all unprocessed data."""self.__starttag_text = Noneself.rawdata = ''self.stack = []self.lasttag = '???'self.nomoretags = 0self.literal = 0markupbase.ParserBase.reset(self)def setnomoretags(self):"""Enter literal mode (CDATA) till EOF.Intended for derived classes only."""self.nomoretags = self.literal = 1def setliteral(self, *args):"""Enter literal mode (CDATA).Intended for derived classes only."""self.literal = 1def feed(self, data):"""Feed some data to the parser.Call this as often as you want, with as little or as much textas you want (may include '\n'). (This just saves the text,all the processing is done by goahead().)"""self.rawdata = self.rawdata + dataself.goahead(0)def close(self):"""Handle the remaining data."""self.goahead(1)def error(self, message):raise SGMLParseError(message)# Internal -- handle data as far as reasonable. May leave state# and data to be processed by a subsequent call. If 'end' is# true, force handling all data as if followed by EOF marker.def goahead(self, end):rawdata = self.rawdatai = 0n = len(rawdata)while i < n:if self.nomoretags:self.handle_data(rawdata[i:n])i = nbreakmatch = interesting.search(rawdata, i)if match:j = match.start()else:j = nif i < j:self.handle_data(rawdata[i:j])i = jif i == n:breakif rawdata[i] == '<':if starttagopen.match(rawdata, i):if self.literal:self.handle_data(rawdata[i])i = i + 1continuek = self.parse_starttag(i)if k < 0:breaki = kcontinueif rawdata.startswith("</", i):k = self.parse_endtag(i)if k < 0:breaki = kself.literal = 0continueif self.literal:if n > (i + 1):self.handle_data("<")i = i + 1else:# incompletebreakcontinueif rawdata.startswith("<!--", i):# Strictly speaking, a comment is --.*--# within a declaration tag <!...>.# This should be removed,# and comments handled only in parse_declaration.k = self.parse_comment(i)if k < 0:breaki = kcontinueif rawdata.startswith("<?", i):k = self.parse_pi(i)if k < 0:breaki = i + kcontinueif rawdata.startswith("<!", i):# This is some sort of declaration; in "HTML as# deployed," this should only be the document type# declaration ("<!DOCTYPE html...>").k = self.parse_declaration(i)if k < 0:breaki = kcontinueelif rawdata[i] == '&':if self.literal:self.handle_data(rawdata[i])i = i + 1continuematch = charref.match(rawdata, i)if match:name = match.group(1)self.handle_charref(name)i = match.end(0)if rawdata[i - 1] != ';':i = i - 1continuematch = entityref.match(rawdata, i)if match:name = match.group(1)self.handle_entityref(name)i = match.end(0)if rawdata[i - 1] != ';':i = i - 1continueelse:self.error('neither < nor & ??')# We get here only if incomplete matches but# nothing elsematch = incomplete.match(rawdata, i)if not match:self.handle_data(rawdata[i])i = i + 1continuej = match.end(0)if j == n:break # Really incompleteself.handle_data(rawdata[i:j])i = j# end whileif end and i < n:self.handle_data(rawdata[i:n])i = nself.rawdata = rawdata[i:]# XXX if end: check for empty stack# Extensions for the DOCTYPE scanner:_decl_otherchars = '='# Internal -- parse processing instr, return length or -1 if not terminateddef parse_pi(self, i):rawdata = self.rawdataif rawdata[i:i + 2] != '<?':self.error('unexpected call to parse_pi()')match = piclose.search(rawdata, i + 2)if not match:return -1j = match.start(0)self.handle_pi(rawdata[i + 2: j])j = match.end(0)return j - idef get_starttag_text(self):return self.__starttag_text# Internal -- handle starttag, return length or -1 if not terminateddef parse_starttag(self, i):self.__starttag_text = Nonestart_pos = irawdata = self.rawdataif shorttagopen.match(rawdata, i):# SGML shorthand: <tag/data/ == <tag>data</tag># XXX Can data contain &... (entity or char refs)?# XXX Can data contain < or > (tag characters)?# XXX Can there be whitespace before the first /?match = shorttag.match(rawdata, i)if not match:return -1tag, data = match.group(1, 2)self.__starttag_text = '<%s/' % tagtag = tag.lower()k = match.end(0)self.finish_shorttag(tag, data)self.__starttag_text = rawdata[start_pos:match.end(1) + 1]return k# XXX The following should skip matching quotes (' or ")# As a shortcut way to exit, this isn't so bad, but shouldn't# be used to locate the actual end of the start tag since the# < or > characters may be embedded in an attribute value.match = endbracket.search(rawdata, i + 1)if not match:return -1j = match.start(0)# Now parse the data between i + 1 and j into a tag and attrsattrs = []if rawdata[i:i + 2] == '<>':# SGML shorthand: <> == <last open tag seen>k = jtag = self.lasttagelse:match = tagfind.match(rawdata, i + 1)if not match:self.error('unexpected call to parse_starttag')k = match.end(0)tag = rawdata[i + 1:k].lower()self.lasttag = tagwhile k < j:match = attrfind.match(rawdata, k)if not match:breakattrname, rest, attrvalue = match.group(1, 2, 3)if not rest:attrvalue = attrnameelse:if (attrvalue[:1] == "'" == attrvalue[-1:] orattrvalue[:1] == '"' == attrvalue[-1:]):# strip quotesattrvalue = attrvalue[1:-1]attrvalue = self.entity_or_charref.sub(self._convert_ref, attrvalue)attrs.append((attrname.lower(), attrvalue))k = match.end(0)if rawdata[j] == '>':j = j + 1self.__starttag_text = rawdata[start_pos:j]self.finish_starttag(tag, attrs)return j# Internal -- convert entity or character referencedef _convert_ref(self, match):if match.group(2):return self.convert_charref(match.group(2)) or \'&#%s%s' % match.groups()[1:]elif match.group(3):return self.convert_entityref(match.group(1)) or \'&%s;' % match.group(1)else:return '&%s' % match.group(1)# Internal -- parse endtagdef parse_endtag(self, i):rawdata = self.rawdatamatch = endbracket.search(rawdata, i + 1)if not match:return -1j = match.start(0)tag = rawdata[i + 2:j].strip().lower()if rawdata[j] == '>':j = j + 1self.finish_endtag(tag)return j# Internal -- finish parsing of <tag/data/ (same as <tag>data</tag>)def finish_shorttag(self, tag, data):self.finish_starttag(tag, [])self.handle_data(data)self.finish_endtag(tag)# Internal -- finish processing of start tag# Return -1 for unknown tag, 0 for open-only tag, 1 for balanced tagdef finish_starttag(self, tag, attrs):try:method = getattr(self, 'start_' + tag)except AttributeError:try:method = getattr(self, 'do_' + tag)except AttributeError:self.unknown_starttag(tag, attrs)return -1else:self.handle_starttag(tag, method, attrs)return 0else:self.stack.append(tag)self.handle_starttag(tag, method, attrs)return 1# Internal -- finish processing of end tagdef finish_endtag(self, tag):if not tag:found = len(self.stack) - 1if found < 0:self.unknown_endtag(tag)returnelse:if tag not in self.stack:try:method = getattr(self, 'end_' + tag)except AttributeError:self.unknown_endtag(tag)else:self.report_unbalanced(tag)returnfound = len(self.stack)for i in range(found):if self.stack[i] == tag:found = iwhile len(self.stack) > found:tag = self.stack[-1]try:method = getattr(self, 'end_' + tag)except AttributeError:method = Noneif method:self.handle_endtag(tag, method)else:self.unknown_endtag(tag)del self.stack[-1]# Overridable -- handle start tagdef handle_starttag(self, tag, method, attrs):method(attrs)# Overridable -- handle end tagdef handle_endtag(self, tag, method):method()# Example -- report an unbalanced </...> tag.def report_unbalanced(self, tag):if self.verbose:print('*** Unbalanced </' + tag + '>')print('*** Stack:', self.stack)def convert_charref(self, name):"""Convert character reference, may be overridden."""try:n = int(name)except ValueError:returnif not 0 <= n <= 127:returnreturn self.convert_codepoint(n)def convert_codepoint(self, codepoint):return chr(codepoint)def handle_charref(self, name):"""Handle character reference, no need to override."""replacement = self.convert_charref(name)if replacement is None:self.unknown_charref(name)else:self.handle_data(replacement)# Definition of entities -- derived classes may overrideentitydefs = \{'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}def convert_entityref(self, name):"""Convert entity references.As an alternative to overriding this method; one can tailor theresults by setting up the self.entitydefs mapping appropriately."""table = self.entitydefsif name in table:return table[name]else:returndef handle_entityref(self, name):"""Handle entity references, no need to override."""replacement = self.convert_entityref(name)if replacement is None:self.unknown_entityref(name)else:self.handle_data(replacement)# Example -- handle data, should be overriddendef handle_data(self, data):pass# Example -- handle comment, could be overriddendef handle_comment(self, data):pass# Example -- handle declaration, could be overriddendef handle_decl(self, decl):pass# Example -- handle processing instruction, could be overriddendef handle_pi(self, data):pass# To be overridden -- handlers for unknown objectsdef unknown_starttag(self, tag, attrs):passdef unknown_endtag(self, tag):passdef unknown_charref(self, ref):passdef unknown_entityref(self, ref):passclass TestSGMLParser(SGMLParser):def __init__(self, verbose=0):self.testdata = ""SGMLParser.__init__(self, verbose)def handle_data(self, data):self.testdata = self.testdata + dataif len(repr(self.testdata)) >= 70:self.flush()def flush(self):data = self.testdataif data:self.testdata = ""print('data:', repr(data))def handle_comment(self, data):self.flush()r = repr(data)if len(r) > 68:r = r[:32] + '...' + r[-32:]print('comment:', r)def unknown_starttag(self, tag, attrs):self.flush()if not attrs:print('start tag: <' + tag + '>')else:print('start tag: <' + tag, end=' ')for name, value in attrs:print(name + '=' + '"' + value + '"', end=' ')print('>')def unknown_endtag(self, tag):self.flush()print('end tag: </' + tag + '>')def unknown_entityref(self, ref):self.flush()print('*** unknown entity ref: &' + ref + ';')def unknown_charref(self, ref):self.flush()print('*** unknown char ref: &#' + ref + ';')def unknown_decl(self, data):self.flush()print('*** unknown decl: [' + data + ']')def close(self):SGMLParser.close(self)self.flush()def test(args=None):import sysif args is None:args = sys.argv[1:]if args and args[0] == '-s':args = args[1:]klass = SGMLParserelse:klass = TestSGMLParserif args:file = args[0]else:file = 'test.html'if file == '-':f = sys.stdinelse:try:f = open(file, 'r')except IOError as msg:print(file, ":", msg)sys.exit(1)data = f.read()if f is not sys.stdin:f.close()x = klass()for c in data:x.feed(c)x.close()if __name__ == '__main__':test()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。