Some more updates

This commit is contained in:
Miroslav Stampar 2019-03-27 16:36:32 +01:00
parent fbd42228f8
commit c27820dc0e
9 changed files with 626 additions and 79 deletions

View File

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import binascii import binascii
import os import os
import random import random
import uuid
class WichmannHill(random.Random): class WichmannHill(random.Random):
""" """
@ -159,3 +160,7 @@ class WichmannHill(random.Random):
y = (y + a) % 256 or 1 y = (y + a) % 256 or 1
z = (z + a) % 256 or 1 z = (z + a) % 256 or 1
self.__whseed(x, y, z) self.__whseed(x, y, z)
# Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py
def choose_boundary():
return uuid.uuid4().hex

View File

@ -24,3 +24,11 @@ def dirtyPatches():
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440 # Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None) 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 = _

View File

@ -17,7 +17,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # 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 = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} 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) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

View File

@ -97,11 +97,3 @@ class HTTPSConnection(_http_client.HTTPSConnection):
class HTTPSHandler(_urllib.request.HTTPSHandler): class HTTPSHandler(_urllib.request.HTTPSHandler):
def https_open(self, req): def https_open(self, req):
return self.do_open(HTTPSConnection if ssl else _http_client.HTTPSConnection, 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 = _

View File

@ -6,7 +6,6 @@ See the file 'LICENSE' for copying permission
""" """
import base64 import base64
import BaseHTTPServer
import datetime import datetime
import io import io
import re import re
@ -14,6 +13,7 @@ import time
from lib.core.bigarray import BigArray from lib.core.bigarray import BigArray
from lib.core.settings import VERSION 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 # Reference: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html
# http://www.softwareishard.com/har/viewer/ # http://www.softwareishard.com/har/viewer/
@ -207,7 +207,7 @@ class FakeSocket:
def makefile(self, *args, **kwargs): def makefile(self, *args, **kwargs):
return self._file return self._file
class HTTPRequest(BaseHTTPServer.BaseHTTPRequestHandler): class HTTPRequest(_BaseHTTPServer.BaseHTTPRequestHandler):
# Original source: # Original source:
# https://stackoverflow.com/questions/4685217/parse-raw-http-headers # https://stackoverflow.com/questions/4685217/parse-raw-http-headers

551
lib/utils/sgmllib.py Normal file
View 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()

View File

@ -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

View File

@ -93,11 +93,22 @@ else:
handler.setLevel(logging.DEBUG) handler.setLevel(logging.DEBUG)
_logger.addHandler(handler) _logger.addHandler(handler)
import sys, urllib, urllib2, types, mimetools, copy, urlparse, \ try:
htmlentitydefs, re, random from six.moves import cStringIO as _cStringIO
from cStringIO import StringIO 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 :-( # monkeypatch to fix http://www.python.org/sf/803422 :-(
sgmllib.charref = re.compile("&#(x?[0-9a-fA-F]+)[^0-9a-fA-F]") sgmllib.charref = re.compile("&#(x?[0-9a-fA-F]+)[^0-9a-fA-F]")
@ -174,20 +185,20 @@ string.
if not doseq: if not doseq:
# preserve old behavior # preserve old behavior
for k, v in query: for k, v in query:
k = urllib.quote_plus(str(k)) k = _urllib.parse.quote_plus(str(k))
v = urllib.quote_plus(str(v)) v = _urllib.parse.quote_plus(str(v))
l.append(k + '=' + v) l.append(k + '=' + v)
else: else:
for k, v in query: for k, v in query:
k = urllib.quote_plus(str(k)) k = _urllib.parse.quote_plus(str(k))
if type(v) == types.StringType: if type(v) == types.StringType:
v = urllib.quote_plus(v) v = _urllib.parse.quote_plus(v)
l.append(k + '=' + v) l.append(k + '=' + v)
elif type(v) == types.UnicodeType: elif type(v) == types.UnicodeType:
# is there a reasonable way to convert to ASCII? # is there a reasonable way to convert to ASCII?
# encode generates a string, but "replace" or "ignore" # encode generates a string, but "replace" or "ignore"
# lose information and "strict" can raise UnicodeError # 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) l.append(k + '=' + v)
else: else:
try: try:
@ -195,12 +206,12 @@ string.
x = len(v) x = len(v)
except TypeError: except TypeError:
# not a sequence # not a sequence
v = urllib.quote_plus(str(v)) v = _urllib.parse.quote_plus(str(v))
l.append(k + '=' + v) l.append(k + '=' + v)
else: else:
# loop over the sequence # loop over the sequence
for elt in v: for elt in v:
l.append(k + '=' + urllib.quote_plus(str(elt))) l.append(k + '=' + _urllib.parse.quote_plus(str(elt)))
return '&'.join(l) return '&'.join(l)
def unescape(data, entities, encoding=DEFAULT_ENCODING): def unescape(data, entities, encoding=DEFAULT_ENCODING):
@ -243,20 +254,19 @@ def unescape_charref(data, encoding):
return repl return repl
def get_entitydefs(): def get_entitydefs():
import htmlentitydefs
from codecs import latin_1_decode from codecs import latin_1_decode
entitydefs = {} entitydefs = {}
try: try:
htmlentitydefs.name2codepoint _html_entities.name2codepoint
except AttributeError: except AttributeError:
entitydefs = {} entitydefs = {}
for name, char in htmlentitydefs.entitydefs.items(): for name, char in _html_entities.entitydefs.items():
uc = latin_1_decode(char)[0] uc = latin_1_decode(char)[0]
if uc.startswith("&#") and uc.endswith(";"): if uc.startswith("&#") and uc.endswith(";"):
uc = unescape_charref(uc[2:-1], None) uc = unescape_charref(uc[2:-1], None)
entitydefs["&%s;" % name] = uc entitydefs["&%s;" % name] = uc
else: else:
for name, codepoint in htmlentitydefs.name2codepoint.items(): for name, codepoint in _html_entities.name2codepoint.items():
entitydefs["&%s;" % name] = unichr(codepoint) entitydefs["&%s;" % name] = unichr(codepoint)
return entitydefs return entitydefs
@ -927,14 +937,14 @@ else:
def ParseResponseEx(response, def ParseResponseEx(response,
select_default=False, select_default=False,
form_parser_class=FormParser, form_parser_class=FormParser,
request_class=urllib2.Request, request_class=_urllib.request.Request,
entitydefs=None, entitydefs=None,
encoding=DEFAULT_ENCODING, encoding=DEFAULT_ENCODING,
# private # private
_urljoin=urlparse.urljoin, _urljoin=_urllib.parse.urljoin,
_urlparse=urlparse.urlparse, _urlparse=_urllib.parse.urlparse,
_urlunparse=urlparse.urlunparse, _urlunparse=_urllib.parse.urlunparse,
): ):
"""Identical to ParseResponse, except that: """Identical to ParseResponse, except that:
@ -961,14 +971,14 @@ def ParseResponseEx(response,
def ParseFileEx(file, base_uri, def ParseFileEx(file, base_uri,
select_default=False, select_default=False,
form_parser_class=FormParser, form_parser_class=FormParser,
request_class=urllib2.Request, request_class=_urllib.request.Request,
entitydefs=None, entitydefs=None,
encoding=DEFAULT_ENCODING, encoding=DEFAULT_ENCODING,
# private # private
_urljoin=urlparse.urljoin, _urljoin=_urllib.parse.urljoin,
_urlparse=urlparse.urlparse, _urlparse=_urllib.parse.urlparse,
_urlunparse=urlparse.urlunparse, _urlunparse=_urllib.parse.urlunparse,
): ):
"""Identical to ParseFile, except that: """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 pick the first item as the default if none are selected in the HTML
form_parser_class: class to instantiate and use to pass form_parser_class: class to instantiate and use to pass
request_class: class to return from .click() method (default is request_class: class to return from .click() method (default is
urllib2.Request) _urllib.request.Request)
entitydefs: mapping like {"&amp;": "&", ...} containing HTML entity entitydefs: mapping like {"&amp;": "&", ...} containing HTML entity
definitions (a sensible default is used) definitions (a sensible default is used)
encoding: character encoding used for encoding numeric character references encoding: character encoding used for encoding numeric character references
@ -1074,13 +1084,13 @@ def _ParseFileEx(file, base_uri,
select_default=False, select_default=False,
ignore_errors=False, ignore_errors=False,
form_parser_class=FormParser, form_parser_class=FormParser,
request_class=urllib2.Request, request_class=_urllib.request.Request,
entitydefs=None, entitydefs=None,
backwards_compat=True, backwards_compat=True,
encoding=DEFAULT_ENCODING, encoding=DEFAULT_ENCODING,
_urljoin=urlparse.urljoin, _urljoin=_urllib.parse.urljoin,
_urlparse=urlparse.urlparse, _urlparse=_urllib.parse.urlparse,
_urlunparse=urlparse.urlunparse, _urlunparse=_urllib.parse.urlunparse,
): ):
if backwards_compat: if backwards_compat:
deprecation("operating in backwards-compatibility mode", 1) deprecation("operating in backwards-compatibility mode", 1)
@ -1316,8 +1326,8 @@ class ScalarControl(Control):
self._clicked = False self._clicked = False
self._urlparse = urlparse.urlparse self._urlparse = _urllib.parse.urlparse
self._urlunparse = urlparse.urlunparse self._urlunparse = _urllib.parse.urlunparse
def __getattr__(self, name): def __getattr__(self, name):
if name == "value": if name == "value":
@ -1437,7 +1447,7 @@ class FileControl(ScalarControl):
# assert _name == self.name and _value == '' # assert _name == self.name and _value == ''
if len(self._upload_data) < 2: if len(self._upload_data) < 2:
if len(self._upload_data) == 0: if len(self._upload_data) == 0:
file_object = StringIO() file_object = _cStringIO()
content_type = "application/octet-stream" content_type = "application/octet-stream"
filename = "" filename = ""
else: else:
@ -1515,7 +1525,7 @@ class IsindexControl(ScalarControl):
ISINDEX elements outside of FORMs are ignored. If you want to submit one ISINDEX elements outside of FORMs are ignored. If you want to submit one
by hand, do it like so: 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) result = urllib2.urlopen(url)
""" """
@ -1529,7 +1539,7 @@ class IsindexControl(ScalarControl):
def _totally_ordered_pairs(self): def _totally_ordered_pairs(self):
return [] 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", # Relative URL for ISINDEX submission: instead of "foo=bar+baz",
# want "bar+baz". # want "bar+baz".
# This doesn't seem to be specified in HTML 4.01 spec. (ISINDEX is # 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. # Submission of ISINDEX is explained in the HTML 3.2 spec, though.
parts = self._urlparse(form.action) parts = self._urlparse(form.action)
rest, (query, frag) = parts[:-2], parts[-2:] 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) url = self._urlunparse(parts)
req_data = url, None, [] req_data = url, None, []
@ -2456,7 +2466,7 @@ class SubmitControl(ScalarControl):
def is_of_kind(self, kind): return kind == "clickable" 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 self._clicked = coord
r = form._switch_click(return_type, request_class) r = form._switch_click(return_type, request_class)
self._clicked = False self._clicked = False
@ -2752,7 +2762,7 @@ class HTMLForm:
def __init__(self, action, method="GET", def __init__(self, action, method="GET",
enctype=None, enctype=None,
name=None, attrs=None, name=None, attrs=None,
request_class=urllib2.Request, request_class=_urllib.request.Request,
forms=None, labels=None, id_to_labels=None, forms=None, labels=None, id_to_labels=None,
backwards_compat=True): backwards_compat=True):
""" """
@ -2784,8 +2794,8 @@ class HTMLForm:
self.backwards_compat = backwards_compat # note __setattr__ self.backwards_compat = backwards_compat # note __setattr__
self._urlunparse = urlparse.urlunparse self._urlunparse = _urllib.parse.urlunparse
self._urlparse = urlparse.urlparse self._urlparse = _urllib.parse.urlparse
def __getattr__(self, name): def __getattr__(self, name):
if name == "backwards_compat": if name == "backwards_compat":
@ -3083,11 +3093,11 @@ class HTMLForm:
# Form submission methods, applying only to clickable controls. # Form submission methods, applying only to clickable controls.
def click(self, name=None, type=None, id=None, nr=0, coord=(1,1), 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): label=None):
"""Return request that would result from clicking on a control. """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). urllib2.urlopen (or ClientCookie.urlopen).
Only some control types (INPUT/SUBMIT & BUTTON/SUBMIT buttons and Only some control types (INPUT/SUBMIT & BUTTON/SUBMIT buttons and
@ -3112,7 +3122,7 @@ class HTMLForm:
def click_request_data(self, def click_request_data(self,
name=None, type=None, id=None, name=None, type=None, id=None,
nr=0, coord=(1,1), nr=0, coord=(1,1),
request_class=urllib2.Request, request_class=_urllib.request.Request,
label=None): label=None):
"""As for click method, but return a tuple (url, data, headers). """As for click method, but return a tuple (url, data, headers).
@ -3124,14 +3134,14 @@ class HTMLForm:
# instead! # instead!
import urllib import urllib
url, data, hdrs = form.click_request_data() 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 # Untested. I don't know of any reason to use httplib -- you can get
# just as much control with urllib2. # just as much control with urllib2.
import httplib, urlparse import httplib, urlparse
url, data, hdrs = form.click_request_data() url, data, hdrs = form.click_request_data()
tup = urlparse(url) 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) conn = httplib.HTTPConnection(host)
if data: if data:
httplib.request("POST", path, data, hdrs) httplib.request("POST", path, data, hdrs)
@ -3303,7 +3313,7 @@ class HTMLForm:
assert False assert False
def _click(self, name, type, id, label, nr, coord, return_type, def _click(self, name, type, id, label, nr, coord, return_type,
request_class=urllib2.Request): request_class=_urllib.request.Request):
try: try:
control = self._find_control( control = self._find_control(
name, type, "clickable", id, label, None, nr) name, type, "clickable", id, label, None, nr)
@ -3342,7 +3352,7 @@ class HTMLForm:
def _request_data(self): def _request_data(self):
"""Return a tuple (url, data, headers).""" """Return a tuple (url, data, headers)."""
method = self.method.upper() 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) parts = self._urlparse(self.action)
rest, (query, frag) = parts[:-2], parts[-2:] rest, (query, frag) = parts[:-2], parts[-2:]
@ -3361,7 +3371,7 @@ class HTMLForm:
return (uri, self._pairs(), return (uri, self._pairs(),
[("Content-Type", self.enctype)]) [("Content-Type", self.enctype)])
elif self.enctype == "multipart/form-data": elif self.enctype == "multipart/form-data":
data = StringIO() data = _cStringIO()
http_hdrs = [] http_hdrs = []
mw = MimeWriter(data, http_hdrs) mw = MimeWriter(data, http_hdrs)
f = mw.startmultipartbody("form-data", add_to_http_hdrs=True, f = mw.startmultipartbody("form-data", add_to_http_hdrs=True,
@ -3376,7 +3386,7 @@ class HTMLForm:
else: else:
raise ValueError("Unknown method '%s'" % method) 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 # This is called by HTMLForm and clickable Controls to hide switching
# on return_type. # on return_type.
if return_type == "pairs": if return_type == "pairs":

View File

@ -29,9 +29,9 @@ import sys
import urllib import urllib
import urllib2 import urllib2
from lib.core.compat import choose_boundary
from lib.core.exception import SqlmapDataException from lib.core.exception import SqlmapDataException
class Callable: class Callable:
def __init__(self, anycallable): def __init__(self, anycallable):
self.__call__ = anycallable self.__call__ = anycallable
@ -75,7 +75,7 @@ class MultipartPostHandler(urllib2.BaseHandler):
def multipart_encode(vars, files, boundary=None, buf=None): def multipart_encode(vars, files, boundary=None, buf=None):
if boundary is None: if boundary is None:
boundary = mimetools.choose_boundary() boundary = choose_boundary()
if buf is None: if buf is None:
buf = "" buf = ""