mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 09:36:35 +03:00
Some more updates
This commit is contained in:
parent
fbd42228f8
commit
c27820dc0e
|
@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
|
|||
import binascii
|
||||
import os
|
||||
import random
|
||||
import uuid
|
||||
|
||||
class WichmannHill(random.Random):
|
||||
"""
|
||||
|
@ -159,3 +160,7 @@ class WichmannHill(random.Random):
|
|||
y = (y + a) % 256 or 1
|
||||
z = (z + a) % 256 or 1
|
||||
self.__whseed(x, y, z)
|
||||
|
||||
# Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py
|
||||
def choose_boundary():
|
||||
return uuid.uuid4().hex
|
|
@ -24,3 +24,11 @@ def dirtyPatches():
|
|||
|
||||
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
|
||||
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
|
||||
|
||||
# Reference: http://bugs.python.org/issue17849
|
||||
if hasattr(_http_client, "LineAndFileWrapper"):
|
||||
def _(self, *args):
|
||||
return self._readline()
|
||||
|
||||
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
|
||||
_http_client.LineAndFileWrapper.readline = _
|
||||
|
|
|
@ -17,7 +17,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
|
|||
from lib.core.enums import OS
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.3.3.61"
|
||||
VERSION = "1.3.3.62"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||
|
|
|
@ -97,11 +97,3 @@ class HTTPSConnection(_http_client.HTTPSConnection):
|
|||
class HTTPSHandler(_urllib.request.HTTPSHandler):
|
||||
def https_open(self, req):
|
||||
return self.do_open(HTTPSConnection if ssl else _http_client.HTTPSConnection, req)
|
||||
|
||||
# Bug fix (http://bugs.python.org/issue17849)
|
||||
|
||||
def _(self, *args):
|
||||
return self._readline()
|
||||
|
||||
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
|
||||
_http_client.LineAndFileWrapper.readline = _
|
||||
|
|
|
@ -6,7 +6,6 @@ See the file 'LICENSE' for copying permission
|
|||
"""
|
||||
|
||||
import base64
|
||||
import BaseHTTPServer
|
||||
import datetime
|
||||
import io
|
||||
import re
|
||||
|
@ -14,6 +13,7 @@ import time
|
|||
|
||||
from lib.core.bigarray import BigArray
|
||||
from lib.core.settings import VERSION
|
||||
from thirdparty.six.moves import BaseHTTPServer as _BaseHTTPServer
|
||||
|
||||
# Reference: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html
|
||||
# http://www.softwareishard.com/har/viewer/
|
||||
|
@ -207,7 +207,7 @@ class FakeSocket:
|
|||
def makefile(self, *args, **kwargs):
|
||||
return self._file
|
||||
|
||||
class HTTPRequest(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
class HTTPRequest(_BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
# Original source:
|
||||
# https://stackoverflow.com/questions/4685217/parse-raw-http-headers
|
||||
|
||||
|
|
551
lib/utils/sgmllib.py
Normal file
551
lib/utils/sgmllib.py
Normal file
|
@ -0,0 +1,551 @@
|
|||
"""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_function
|
||||
|
||||
import _markupbase
|
||||
import re
|
||||
|
||||
__all__ = ["SGMLParser", "SGMLParseError"]
|
||||
|
||||
# Regular expressions used for parsing
|
||||
|
||||
interesting = 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 override
|
||||
entity_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 = verbose
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
"""Reset this instance. Loses all unprocessed data."""
|
||||
self.__starttag_text = None
|
||||
self.rawdata = ''
|
||||
self.stack = []
|
||||
self.lasttag = '???'
|
||||
self.nomoretags = 0
|
||||
self.literal = 0
|
||||
_markupbase.ParserBase.reset(self)
|
||||
|
||||
def setnomoretags(self):
|
||||
"""Enter literal mode (CDATA) till EOF.
|
||||
|
||||
Intended for derived classes only.
|
||||
"""
|
||||
self.nomoretags = self.literal = 1
|
||||
|
||||
def setliteral(self, *args):
|
||||
"""Enter literal mode (CDATA).
|
||||
|
||||
Intended for derived classes only.
|
||||
"""
|
||||
self.literal = 1
|
||||
|
||||
def feed(self, data):
|
||||
"""Feed some data to the parser.
|
||||
|
||||
Call this as often as you want, with as little or as much text
|
||||
as you want (may include '\n'). (This just saves the text,
|
||||
all the processing is done by goahead().)
|
||||
"""
|
||||
|
||||
self.rawdata = self.rawdata + data
|
||||
self.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.rawdata
|
||||
i = 0
|
||||
n = len(rawdata)
|
||||
while i < n:
|
||||
if self.nomoretags:
|
||||
self.handle_data(rawdata[i:n])
|
||||
i = n
|
||||
break
|
||||
match = interesting.search(rawdata, i)
|
||||
if match: j = match.start()
|
||||
else: j = n
|
||||
if i < j:
|
||||
self.handle_data(rawdata[i:j])
|
||||
i = j
|
||||
if i == n: break
|
||||
if rawdata[i] == '<':
|
||||
if starttagopen.match(rawdata, i):
|
||||
if self.literal:
|
||||
self.handle_data(rawdata[i])
|
||||
i = i+1
|
||||
continue
|
||||
k = self.parse_starttag(i)
|
||||
if k < 0: break
|
||||
i = k
|
||||
continue
|
||||
if rawdata.startswith("</", i):
|
||||
k = self.parse_endtag(i)
|
||||
if k < 0: break
|
||||
i = k
|
||||
self.literal = 0
|
||||
continue
|
||||
if self.literal:
|
||||
if n > (i + 1):
|
||||
self.handle_data("<")
|
||||
i = i+1
|
||||
else:
|
||||
# incomplete
|
||||
break
|
||||
continue
|
||||
if 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: break
|
||||
i = k
|
||||
continue
|
||||
if rawdata.startswith("<?", i):
|
||||
k = self.parse_pi(i)
|
||||
if k < 0: break
|
||||
i = i+k
|
||||
continue
|
||||
if 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: break
|
||||
i = k
|
||||
continue
|
||||
elif rawdata[i] == '&':
|
||||
if self.literal:
|
||||
self.handle_data(rawdata[i])
|
||||
i = i+1
|
||||
continue
|
||||
match = charref.match(rawdata, i)
|
||||
if match:
|
||||
name = match.group(1)
|
||||
self.handle_charref(name)
|
||||
i = match.end(0)
|
||||
if rawdata[i-1] != ';': i = i-1
|
||||
continue
|
||||
match = entityref.match(rawdata, i)
|
||||
if match:
|
||||
name = match.group(1)
|
||||
self.handle_entityref(name)
|
||||
i = match.end(0)
|
||||
if rawdata[i-1] != ';': i = i-1
|
||||
continue
|
||||
else:
|
||||
self.error('neither < nor & ??')
|
||||
# We get here only if incomplete matches but
|
||||
# nothing else
|
||||
match = incomplete.match(rawdata, i)
|
||||
if not match:
|
||||
self.handle_data(rawdata[i])
|
||||
i = i+1
|
||||
continue
|
||||
j = match.end(0)
|
||||
if j == n:
|
||||
break # Really incomplete
|
||||
self.handle_data(rawdata[i:j])
|
||||
i = j
|
||||
# end while
|
||||
if end and i < n:
|
||||
self.handle_data(rawdata[i:n])
|
||||
i = n
|
||||
self.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 terminated
|
||||
def parse_pi(self, i):
|
||||
rawdata = self.rawdata
|
||||
if rawdata[i:i+2] != '<?':
|
||||
self.error('unexpected call to parse_pi()')
|
||||
match = piclose.search(rawdata, i+2)
|
||||
if not match:
|
||||
return -1
|
||||
j = match.start(0)
|
||||
self.handle_pi(rawdata[i+2: j])
|
||||
j = match.end(0)
|
||||
return j-i
|
||||
|
||||
def get_starttag_text(self):
|
||||
return self.__starttag_text
|
||||
|
||||
# Internal -- handle starttag, return length or -1 if not terminated
|
||||
def parse_starttag(self, i):
|
||||
self.__starttag_text = None
|
||||
start_pos = i
|
||||
rawdata = self.rawdata
|
||||
if 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 -1
|
||||
tag, data = match.group(1, 2)
|
||||
self.__starttag_text = '<%s/' % tag
|
||||
tag = 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 -1
|
||||
j = match.start(0)
|
||||
# Now parse the data between i+1 and j into a tag and attrs
|
||||
attrs = []
|
||||
if rawdata[i:i+2] == '<>':
|
||||
# SGML shorthand: <> == <last open tag seen>
|
||||
k = j
|
||||
tag = self.lasttag
|
||||
else:
|
||||
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 = tag
|
||||
while k < j:
|
||||
match = attrfind.match(rawdata, k)
|
||||
if not match: break
|
||||
attrname, rest, attrvalue = match.group(1, 2, 3)
|
||||
if not rest:
|
||||
attrvalue = attrname
|
||||
else:
|
||||
if (attrvalue[:1] == "'" == attrvalue[-1:] or
|
||||
attrvalue[:1] == '"' == attrvalue[-1:]):
|
||||
# strip quotes
|
||||
attrvalue = 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+1
|
||||
self.__starttag_text = rawdata[start_pos:j]
|
||||
self.finish_starttag(tag, attrs)
|
||||
return j
|
||||
|
||||
# Internal -- convert entity or character reference
|
||||
def _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 endtag
|
||||
def parse_endtag(self, i):
|
||||
rawdata = self.rawdata
|
||||
match = endbracket.search(rawdata, i+1)
|
||||
if not match:
|
||||
return -1
|
||||
j = match.start(0)
|
||||
tag = rawdata[i+2:j].strip().lower()
|
||||
if rawdata[j] == '>':
|
||||
j = j+1
|
||||
self.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 tag
|
||||
def 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 -1
|
||||
else:
|
||||
self.handle_starttag(tag, method, attrs)
|
||||
return 0
|
||||
else:
|
||||
self.stack.append(tag)
|
||||
self.handle_starttag(tag, method, attrs)
|
||||
return 1
|
||||
|
||||
# Internal -- finish processing of end tag
|
||||
def finish_endtag(self, tag):
|
||||
if not tag:
|
||||
found = len(self.stack) - 1
|
||||
if found < 0:
|
||||
self.unknown_endtag(tag)
|
||||
return
|
||||
else:
|
||||
if tag not in self.stack:
|
||||
try:
|
||||
method = getattr(self, 'end_' + tag)
|
||||
except AttributeError:
|
||||
self.unknown_endtag(tag)
|
||||
else:
|
||||
self.report_unbalanced(tag)
|
||||
return
|
||||
found = len(self.stack)
|
||||
for i in range(found):
|
||||
if self.stack[i] == tag: found = i
|
||||
while len(self.stack) > found:
|
||||
tag = self.stack[-1]
|
||||
try:
|
||||
method = getattr(self, 'end_' + tag)
|
||||
except AttributeError:
|
||||
method = None
|
||||
if method:
|
||||
self.handle_endtag(tag, method)
|
||||
else:
|
||||
self.unknown_endtag(tag)
|
||||
del self.stack[-1]
|
||||
|
||||
# Overridable -- handle start tag
|
||||
def handle_starttag(self, tag, method, attrs):
|
||||
method(attrs)
|
||||
|
||||
# Overridable -- handle end tag
|
||||
def 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:
|
||||
return
|
||||
if not 0 <= n <= 127:
|
||||
return
|
||||
return 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 override
|
||||
entitydefs = \
|
||||
{'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
|
||||
|
||||
def convert_entityref(self, name):
|
||||
"""Convert entity references.
|
||||
|
||||
As an alternative to overriding this method; one can tailor the
|
||||
results by setting up the self.entitydefs mapping appropriately.
|
||||
"""
|
||||
table = self.entitydefs
|
||||
if name in table:
|
||||
return table[name]
|
||||
else:
|
||||
return
|
||||
|
||||
def 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 overridden
|
||||
def handle_data(self, data):
|
||||
pass
|
||||
|
||||
# Example -- handle comment, could be overridden
|
||||
def handle_comment(self, data):
|
||||
pass
|
||||
|
||||
# Example -- handle declaration, could be overridden
|
||||
def handle_decl(self, decl):
|
||||
pass
|
||||
|
||||
# Example -- handle processing instruction, could be overridden
|
||||
def handle_pi(self, data):
|
||||
pass
|
||||
|
||||
# To be overridden -- handlers for unknown objects
|
||||
def unknown_starttag(self, tag, attrs): pass
|
||||
def unknown_endtag(self, tag): pass
|
||||
def unknown_charref(self, ref): pass
|
||||
def unknown_entityref(self, ref): pass
|
||||
|
||||
|
||||
class TestSGMLParser(SGMLParser):
|
||||
|
||||
def __init__(self, verbose=0):
|
||||
self.testdata = ""
|
||||
SGMLParser.__init__(self, verbose)
|
||||
|
||||
def handle_data(self, data):
|
||||
self.testdata = self.testdata + data
|
||||
if len(repr(self.testdata)) >= 70:
|
||||
self.flush()
|
||||
|
||||
def flush(self):
|
||||
data = self.testdata
|
||||
if 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 sys
|
||||
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args and args[0] == '-s':
|
||||
args = args[1:]
|
||||
klass = SGMLParser
|
||||
else:
|
||||
klass = TestSGMLParser
|
||||
|
||||
if args:
|
||||
file = args[0]
|
||||
else:
|
||||
file = 'test.html'
|
||||
|
||||
if file == '-':
|
||||
f = sys.stdin
|
||||
else:
|
||||
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()
|
19
thirdparty/clientform/__init__.py
vendored
19
thirdparty/clientform/__init__.py
vendored
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/env python2
|
||||
#
|
||||
# Copyright 2007-2008 David McNab
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
pass
|
104
thirdparty/clientform/clientform.py
vendored
104
thirdparty/clientform/clientform.py
vendored
|
@ -93,11 +93,22 @@ else:
|
|||
handler.setLevel(logging.DEBUG)
|
||||
_logger.addHandler(handler)
|
||||
|
||||
import sys, urllib, urllib2, types, mimetools, copy, urlparse, \
|
||||
htmlentitydefs, re, random
|
||||
from cStringIO import StringIO
|
||||
try:
|
||||
from six.moves import cStringIO as _cStringIO
|
||||
from six.moves import urllib as _html_entities
|
||||
from six.moves import urllib as _urllib
|
||||
except ImportError:
|
||||
from thirdparty.six.moves import cStringIO as _cStringIO
|
||||
from thirdparty.six.moves import http_client as _html_entities
|
||||
from thirdparty.six.moves import urllib as _urllib
|
||||
|
||||
try:
|
||||
import sgmllib
|
||||
except ImportError:
|
||||
from lib.utils import sgmllib
|
||||
|
||||
import sys, types, copy, re, random
|
||||
|
||||
import sgmllib
|
||||
# monkeypatch to fix http://www.python.org/sf/803422 :-(
|
||||
sgmllib.charref = re.compile("&#(x?[0-9a-fA-F]+)[^0-9a-fA-F]")
|
||||
|
||||
|
@ -174,20 +185,20 @@ string.
|
|||
if not doseq:
|
||||
# preserve old behavior
|
||||
for k, v in query:
|
||||
k = urllib.quote_plus(str(k))
|
||||
v = urllib.quote_plus(str(v))
|
||||
k = _urllib.parse.quote_plus(str(k))
|
||||
v = _urllib.parse.quote_plus(str(v))
|
||||
l.append(k + '=' + v)
|
||||
else:
|
||||
for k, v in query:
|
||||
k = urllib.quote_plus(str(k))
|
||||
k = _urllib.parse.quote_plus(str(k))
|
||||
if type(v) == types.StringType:
|
||||
v = urllib.quote_plus(v)
|
||||
v = _urllib.parse.quote_plus(v)
|
||||
l.append(k + '=' + v)
|
||||
elif type(v) == types.UnicodeType:
|
||||
# is there a reasonable way to convert to ASCII?
|
||||
# encode generates a string, but "replace" or "ignore"
|
||||
# lose information and "strict" can raise UnicodeError
|
||||
v = urllib.quote_plus(v.encode("ASCII","replace"))
|
||||
v = _urllib.parse.quote_plus(v.encode("ASCII","replace"))
|
||||
l.append(k + '=' + v)
|
||||
else:
|
||||
try:
|
||||
|
@ -195,12 +206,12 @@ string.
|
|||
x = len(v)
|
||||
except TypeError:
|
||||
# not a sequence
|
||||
v = urllib.quote_plus(str(v))
|
||||
v = _urllib.parse.quote_plus(str(v))
|
||||
l.append(k + '=' + v)
|
||||
else:
|
||||
# loop over the sequence
|
||||
for elt in v:
|
||||
l.append(k + '=' + urllib.quote_plus(str(elt)))
|
||||
l.append(k + '=' + _urllib.parse.quote_plus(str(elt)))
|
||||
return '&'.join(l)
|
||||
|
||||
def unescape(data, entities, encoding=DEFAULT_ENCODING):
|
||||
|
@ -243,20 +254,19 @@ def unescape_charref(data, encoding):
|
|||
return repl
|
||||
|
||||
def get_entitydefs():
|
||||
import htmlentitydefs
|
||||
from codecs import latin_1_decode
|
||||
entitydefs = {}
|
||||
try:
|
||||
htmlentitydefs.name2codepoint
|
||||
_html_entities.name2codepoint
|
||||
except AttributeError:
|
||||
entitydefs = {}
|
||||
for name, char in htmlentitydefs.entitydefs.items():
|
||||
for name, char in _html_entities.entitydefs.items():
|
||||
uc = latin_1_decode(char)[0]
|
||||
if uc.startswith("&#") and uc.endswith(";"):
|
||||
uc = unescape_charref(uc[2:-1], None)
|
||||
entitydefs["&%s;" % name] = uc
|
||||
else:
|
||||
for name, codepoint in htmlentitydefs.name2codepoint.items():
|
||||
for name, codepoint in _html_entities.name2codepoint.items():
|
||||
entitydefs["&%s;" % name] = unichr(codepoint)
|
||||
return entitydefs
|
||||
|
||||
|
@ -927,14 +937,14 @@ else:
|
|||
def ParseResponseEx(response,
|
||||
select_default=False,
|
||||
form_parser_class=FormParser,
|
||||
request_class=urllib2.Request,
|
||||
request_class=_urllib.request.Request,
|
||||
entitydefs=None,
|
||||
encoding=DEFAULT_ENCODING,
|
||||
|
||||
# private
|
||||
_urljoin=urlparse.urljoin,
|
||||
_urlparse=urlparse.urlparse,
|
||||
_urlunparse=urlparse.urlunparse,
|
||||
_urljoin=_urllib.parse.urljoin,
|
||||
_urlparse=_urllib.parse.urlparse,
|
||||
_urlunparse=_urllib.parse.urlunparse,
|
||||
):
|
||||
"""Identical to ParseResponse, except that:
|
||||
|
||||
|
@ -961,14 +971,14 @@ def ParseResponseEx(response,
|
|||
def ParseFileEx(file, base_uri,
|
||||
select_default=False,
|
||||
form_parser_class=FormParser,
|
||||
request_class=urllib2.Request,
|
||||
request_class=_urllib.request.Request,
|
||||
entitydefs=None,
|
||||
encoding=DEFAULT_ENCODING,
|
||||
|
||||
# private
|
||||
_urljoin=urlparse.urljoin,
|
||||
_urlparse=urlparse.urlparse,
|
||||
_urlunparse=urlparse.urlunparse,
|
||||
_urljoin=_urllib.parse.urljoin,
|
||||
_urlparse=_urllib.parse.urlparse,
|
||||
_urlunparse=_urllib.parse.urlunparse,
|
||||
):
|
||||
"""Identical to ParseFile, except that:
|
||||
|
||||
|
@ -1006,7 +1016,7 @@ def ParseResponse(response, *args, **kwds):
|
|||
pick the first item as the default if none are selected in the HTML
|
||||
form_parser_class: class to instantiate and use to pass
|
||||
request_class: class to return from .click() method (default is
|
||||
urllib2.Request)
|
||||
_urllib.request.Request)
|
||||
entitydefs: mapping like {"&": "&", ...} containing HTML entity
|
||||
definitions (a sensible default is used)
|
||||
encoding: character encoding used for encoding numeric character references
|
||||
|
@ -1074,13 +1084,13 @@ def _ParseFileEx(file, base_uri,
|
|||
select_default=False,
|
||||
ignore_errors=False,
|
||||
form_parser_class=FormParser,
|
||||
request_class=urllib2.Request,
|
||||
request_class=_urllib.request.Request,
|
||||
entitydefs=None,
|
||||
backwards_compat=True,
|
||||
encoding=DEFAULT_ENCODING,
|
||||
_urljoin=urlparse.urljoin,
|
||||
_urlparse=urlparse.urlparse,
|
||||
_urlunparse=urlparse.urlunparse,
|
||||
_urljoin=_urllib.parse.urljoin,
|
||||
_urlparse=_urllib.parse.urlparse,
|
||||
_urlunparse=_urllib.parse.urlunparse,
|
||||
):
|
||||
if backwards_compat:
|
||||
deprecation("operating in backwards-compatibility mode", 1)
|
||||
|
@ -1316,8 +1326,8 @@ class ScalarControl(Control):
|
|||
|
||||
self._clicked = False
|
||||
|
||||
self._urlparse = urlparse.urlparse
|
||||
self._urlunparse = urlparse.urlunparse
|
||||
self._urlparse = _urllib.parse.urlparse
|
||||
self._urlunparse = _urllib.parse.urlunparse
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == "value":
|
||||
|
@ -1437,7 +1447,7 @@ class FileControl(ScalarControl):
|
|||
# assert _name == self.name and _value == ''
|
||||
if len(self._upload_data) < 2:
|
||||
if len(self._upload_data) == 0:
|
||||
file_object = StringIO()
|
||||
file_object = _cStringIO()
|
||||
content_type = "application/octet-stream"
|
||||
filename = ""
|
||||
else:
|
||||
|
@ -1515,7 +1525,7 @@ class IsindexControl(ScalarControl):
|
|||
ISINDEX elements outside of FORMs are ignored. If you want to submit one
|
||||
by hand, do it like so:
|
||||
|
||||
url = urlparse.urljoin(page_uri, "?"+urllib.quote_plus("my isindex value"))
|
||||
url = _urllib.parse.urljoin(page_uri, "?"+_urllib.parse.quote_plus("my isindex value"))
|
||||
result = urllib2.urlopen(url)
|
||||
|
||||
"""
|
||||
|
@ -1529,7 +1539,7 @@ class IsindexControl(ScalarControl):
|
|||
def _totally_ordered_pairs(self):
|
||||
return []
|
||||
|
||||
def _click(self, form, coord, return_type, request_class=urllib2.Request):
|
||||
def _click(self, form, coord, return_type, request_class=_urllib.request.Request):
|
||||
# Relative URL for ISINDEX submission: instead of "foo=bar+baz",
|
||||
# want "bar+baz".
|
||||
# This doesn't seem to be specified in HTML 4.01 spec. (ISINDEX is
|
||||
|
@ -1537,7 +1547,7 @@ class IsindexControl(ScalarControl):
|
|||
# Submission of ISINDEX is explained in the HTML 3.2 spec, though.
|
||||
parts = self._urlparse(form.action)
|
||||
rest, (query, frag) = parts[:-2], parts[-2:]
|
||||
parts = rest + (urllib.quote_plus(self.value), None)
|
||||
parts = rest + (_urllib.parse.quote_plus(self.value), None)
|
||||
url = self._urlunparse(parts)
|
||||
req_data = url, None, []
|
||||
|
||||
|
@ -2456,7 +2466,7 @@ class SubmitControl(ScalarControl):
|
|||
|
||||
def is_of_kind(self, kind): return kind == "clickable"
|
||||
|
||||
def _click(self, form, coord, return_type, request_class=urllib2.Request):
|
||||
def _click(self, form, coord, return_type, request_class=_urllib.request.Request):
|
||||
self._clicked = coord
|
||||
r = form._switch_click(return_type, request_class)
|
||||
self._clicked = False
|
||||
|
@ -2752,7 +2762,7 @@ class HTMLForm:
|
|||
def __init__(self, action, method="GET",
|
||||
enctype=None,
|
||||
name=None, attrs=None,
|
||||
request_class=urllib2.Request,
|
||||
request_class=_urllib.request.Request,
|
||||
forms=None, labels=None, id_to_labels=None,
|
||||
backwards_compat=True):
|
||||
"""
|
||||
|
@ -2784,8 +2794,8 @@ class HTMLForm:
|
|||
|
||||
self.backwards_compat = backwards_compat # note __setattr__
|
||||
|
||||
self._urlunparse = urlparse.urlunparse
|
||||
self._urlparse = urlparse.urlparse
|
||||
self._urlunparse = _urllib.parse.urlunparse
|
||||
self._urlparse = _urllib.parse.urlparse
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == "backwards_compat":
|
||||
|
@ -3083,11 +3093,11 @@ class HTMLForm:
|
|||
# Form submission methods, applying only to clickable controls.
|
||||
|
||||
def click(self, name=None, type=None, id=None, nr=0, coord=(1,1),
|
||||
request_class=urllib2.Request,
|
||||
request_class=_urllib.request.Request,
|
||||
label=None):
|
||||
"""Return request that would result from clicking on a control.
|
||||
|
||||
The request object is a urllib2.Request instance, which you can pass to
|
||||
The request object is a _urllib.request.Request instance, which you can pass to
|
||||
urllib2.urlopen (or ClientCookie.urlopen).
|
||||
|
||||
Only some control types (INPUT/SUBMIT & BUTTON/SUBMIT buttons and
|
||||
|
@ -3112,7 +3122,7 @@ class HTMLForm:
|
|||
def click_request_data(self,
|
||||
name=None, type=None, id=None,
|
||||
nr=0, coord=(1,1),
|
||||
request_class=urllib2.Request,
|
||||
request_class=_urllib.request.Request,
|
||||
label=None):
|
||||
"""As for click method, but return a tuple (url, data, headers).
|
||||
|
||||
|
@ -3124,14 +3134,14 @@ class HTMLForm:
|
|||
# instead!
|
||||
import urllib
|
||||
url, data, hdrs = form.click_request_data()
|
||||
r = urllib.urlopen(url, data)
|
||||
r = _urllib.request.urlopen(url, data)
|
||||
|
||||
# Untested. I don't know of any reason to use httplib -- you can get
|
||||
# just as much control with urllib2.
|
||||
import httplib, urlparse
|
||||
url, data, hdrs = form.click_request_data()
|
||||
tup = urlparse(url)
|
||||
host, path = tup[1], urlparse.urlunparse((None, None)+tup[2:])
|
||||
host, path = tup[1], _urllib.parse.urlunparse((None, None)+tup[2:])
|
||||
conn = httplib.HTTPConnection(host)
|
||||
if data:
|
||||
httplib.request("POST", path, data, hdrs)
|
||||
|
@ -3303,7 +3313,7 @@ class HTMLForm:
|
|||
assert False
|
||||
|
||||
def _click(self, name, type, id, label, nr, coord, return_type,
|
||||
request_class=urllib2.Request):
|
||||
request_class=_urllib.request.Request):
|
||||
try:
|
||||
control = self._find_control(
|
||||
name, type, "clickable", id, label, None, nr)
|
||||
|
@ -3342,7 +3352,7 @@ class HTMLForm:
|
|||
def _request_data(self):
|
||||
"""Return a tuple (url, data, headers)."""
|
||||
method = self.method.upper()
|
||||
#scheme, netloc, path, parameters, query, frag = urlparse.urlparse(self.action)
|
||||
#scheme, netloc, path, parameters, query, frag = _urllib.parse.urlparse(self.action)
|
||||
parts = self._urlparse(self.action)
|
||||
rest, (query, frag) = parts[:-2], parts[-2:]
|
||||
|
||||
|
@ -3361,7 +3371,7 @@ class HTMLForm:
|
|||
return (uri, self._pairs(),
|
||||
[("Content-Type", self.enctype)])
|
||||
elif self.enctype == "multipart/form-data":
|
||||
data = StringIO()
|
||||
data = _cStringIO()
|
||||
http_hdrs = []
|
||||
mw = MimeWriter(data, http_hdrs)
|
||||
f = mw.startmultipartbody("form-data", add_to_http_hdrs=True,
|
||||
|
@ -3376,7 +3386,7 @@ class HTMLForm:
|
|||
else:
|
||||
raise ValueError("Unknown method '%s'" % method)
|
||||
|
||||
def _switch_click(self, return_type, request_class=urllib2.Request):
|
||||
def _switch_click(self, return_type, request_class=_urllib.request.Request):
|
||||
# This is called by HTMLForm and clickable Controls to hide switching
|
||||
# on return_type.
|
||||
if return_type == "pairs":
|
||||
|
|
4
thirdparty/multipart/multipartpost.py
vendored
4
thirdparty/multipart/multipartpost.py
vendored
|
@ -29,9 +29,9 @@ import sys
|
|||
import urllib
|
||||
import urllib2
|
||||
|
||||
from lib.core.compat import choose_boundary
|
||||
from lib.core.exception import SqlmapDataException
|
||||
|
||||
|
||||
class Callable:
|
||||
def __init__(self, anycallable):
|
||||
self.__call__ = anycallable
|
||||
|
@ -75,7 +75,7 @@ class MultipartPostHandler(urllib2.BaseHandler):
|
|||
|
||||
def multipart_encode(vars, files, boundary=None, buf=None):
|
||||
if boundary is None:
|
||||
boundary = mimetools.choose_boundary()
|
||||
boundary = choose_boundary()
|
||||
|
||||
if buf is None:
|
||||
buf = ""
|
||||
|
|
Loading…
Reference in New Issue
Block a user