66"""
77
88import codecs
9+ import contextlib
910import cookielib
1011import copy
1112import ctypes
102103from lib .core .settings import PARTIAL_VALUE_MARKER
103104from lib .core .settings import ERROR_PARSING_REGEXES
104105from lib .core .settings import PRINTABLE_CHAR_REGEX
105- from lib .core .settings import DUMP_DEL_MARKER
106106from lib .core .settings import SQL_STATEMENTS
107107from lib .core .settings import SUPPORTED_DBMS
108108from lib .core .settings import UNKNOWN_DBMS_VERSION
109109from lib .core .settings import DEFAULT_MSSQL_SCHEMA
110- from lib .core .settings import DUMP_NEWLINE_MARKER
111- from lib .core .settings import DUMP_CR_MARKER
112- from lib .core .settings import DUMP_TAB_MARKER
113110from lib .core .settings import PARAMETER_AMP_MARKER
114111from lib .core .settings import PARAMETER_SEMICOLON_MARKER
115112from lib .core .settings import LARGE_OUTPUT_THRESHOLD
@@ -492,27 +489,17 @@ def isOs(os):
492489
493490# Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/
494491def cachedmethod (f , cache = {}):
495- def g (* args , ** kwargs ):
492+ def _ (* args , ** kwargs ):
496493 key = (f , tuple (args ), frozenset (kwargs .items ()))
497494 if key not in cache :
498495 cache [key ] = f (* args , ** kwargs )
499496 return cache [key ]
500- return g
497+ return _
501498
502499def paramToDict (place , parameters = None ):
503500 """
504501 Split the parameters into names and values, check if these parameters
505502 are within the testable parameters and return in a dictionary.
506-
507- @param place: where sqlmap has to work, can be GET, POST or Cookie.
508- @type place: C{str}
509-
510- @param parameters: parameters string in the format for instance
511- 'p1=v1&p2=v2' (GET and POST) or 'p1=v1;p2=v2' (Cookie).
512- @type parameters: C{str}
513-
514- @return: the parameters in a dictionary.
515- @rtype: C{str}
516503 """
517504
518505 testableParameters = OrderedDict ()
@@ -706,6 +693,10 @@ def singleTimeLogMessage(message, level=logging.INFO, flag=None):
706693 logger .log (level , message )
707694
708695def dataToStdout (data , forceOutput = False ):
696+ """
697+ Writes text to the stdout (console) stream
698+ """
699+
709700 if not kb .get ("threadException" ):
710701 if forceOutput or not getCurrentThreadData ().disableStdOut :
711702 try :
@@ -793,13 +784,10 @@ def readInput(message, default=None, checkBatch=True):
793784 else :
794785 logging ._acquireLock ()
795786 dataToStdout ("\r %s" % message , True )
796- data = raw_input ()
787+ data = raw_input () or default
797788 #data = raw_input(message.encode(sys.stdout.encoding or UNICODE_ENCODING))
798789 logging ._releaseLock ()
799790
800- if not data :
801- data = default
802-
803791 return data
804792
805793def randomRange (start = 0 , stop = 1000 ):
@@ -845,19 +833,6 @@ def checkFile(filename):
845833 if not os .path .exists (filename ):
846834 raise sqlmapFilePathException , "unable to read file '%s'" % filename
847835
848- def replaceNewlineTabs (value , stdout = False ):
849- if value is None :
850- return
851-
852- if stdout :
853- retVal = value .replace ("\n " , " " ).replace ("\r " , " " ).replace ("\t " , " " )
854- else :
855- retVal = value .replace ("\n " , DUMP_NEWLINE_MARKER ).replace ("\r " , DUMP_CR_MARKER ).replace ("\t " , DUMP_TAB_MARKER )
856-
857- retVal = retVal .replace (kb .chars .delimiter , DUMP_DEL_MARKER )
858-
859- return retVal
860-
861836def restoreDumpMarkedChars (value , onlyNewlineTab = False ):
862837 retVal = value
863838
@@ -1070,16 +1045,15 @@ def parseTargetUrl():
10701045 if CUSTOM_INJECTION_MARK_CHAR in conf .url :
10711046 conf .url = conf .url .replace ('?' , URI_QUESTION_MARKER )
10721047
1073- __urlSplit = urlparse .urlsplit (conf .url )
1074- __hostnamePort = __urlSplit [1 ].split (":" ) if not re .search ("\[.+\]" , __urlSplit [1 ]) else filter (None , (re .search ("\[.+\]" , __urlSplit [1 ]).group (0 ), re .search ("\](:(?P<port>\d+))?" , __urlSplit [1 ]).group ("port" )))
1048+ urlSplit = urlparse .urlsplit (conf .url )
1049+ hostnamePort = urlSplit [1 ].split (":" ) if not re .search ("\[.+\]" , urlSplit [1 ]) else filter (None , (re .search ("\[.+\]" , urlSplit [1 ]).group (0 ), re .search ("\](:(?P<port>\d+))?" , urlSplit [1 ]).group ("port" )))
10751050
1076- conf .scheme = __urlSplit [0 ].strip ().lower () if not conf .forceSSL else "https"
1077- conf .path = __urlSplit [2 ].strip ()
1078- conf .hostname = __hostnamePort [0 ].strip ()
1051+ conf .scheme = urlSplit [0 ].strip ().lower () if not conf .forceSSL else "https"
1052+ conf .path = urlSplit [2 ].strip ()
1053+ conf .hostname = hostnamePort [0 ].strip ()
10791054
10801055 conf .ipv6 = conf .hostname != conf .hostname .strip ("[]" )
10811056 conf .hostname = conf .hostname .strip ("[]" )
1082-
10831057
10841058 try :
10851059 _ = conf .hostname .encode ("idna" )
@@ -1090,9 +1064,9 @@ def parseTargetUrl():
10901064 errMsg = "invalid target url"
10911065 raise sqlmapSyntaxException , errMsg
10921066
1093- if len (__hostnamePort ) == 2 :
1067+ if len (hostnamePort ) == 2 :
10941068 try :
1095- conf .port = int (__hostnamePort [1 ])
1069+ conf .port = int (hostnamePort [1 ])
10961070 except :
10971071 errMsg = "invalid target url"
10981072 raise sqlmapSyntaxException , errMsg
@@ -1101,8 +1075,8 @@ def parseTargetUrl():
11011075 else :
11021076 conf .port = 80
11031077
1104- if __urlSplit [3 ]:
1105- conf .parameters [PLACE .GET ] = urldecode (__urlSplit [3 ]) if __urlSplit [3 ] and urlencode (DEFAULT_GET_POST_DELIMITER , None ) not in __urlSplit [3 ] else __urlSplit [3 ]
1078+ if urlSplit [3 ]:
1079+ conf .parameters [PLACE .GET ] = urldecode (urlSplit [3 ]) if urlSplit [3 ] and urlencode (DEFAULT_GET_POST_DELIMITER , None ) not in urlSplit [3 ] else urlSplit [3 ]
11061080
11071081 conf .url = "%s://%s:%d%s" % (conf .scheme , ("[%s]" % conf .hostname ) if conf .ipv6 else conf .hostname , conf .port , conf .path )
11081082 conf .url = conf .url .replace (URI_QUESTION_MARKER , '?' )
@@ -1349,24 +1323,14 @@ def directoryPath(filepath):
13491323 Returns directory path for a given filepath
13501324 """
13511325
1352- if isWindowsDriveLetterPath (filepath ):
1353- retVal = ntpath .dirname (filepath )
1354- else :
1355- retVal = posixpath .dirname (filepath )
1356-
1357- return retVal
1326+ return ntpath .dirname (filepath ) if isWindowsDriveLetterPath (filepath ) else posixpath .dirname (filepath )
13581327
13591328def normalizePath (filepath ):
13601329 """
13611330 Returns normalized string representation of a given filepath
13621331 """
13631332
1364- if isWindowsDriveLetterPath (filepath ):
1365- retVal = ntpath .normpath (filepath )
1366- else :
1367- retVal = posixpath .normpath (filepath )
1368-
1369- return retVal
1333+ return ntpath .normpath (filepath ) if isWindowsDriveLetterPath (filepath ) else posixpath .normpath (filepath )
13701334
13711335def safeStringFormat (format_ , params ):
13721336 """
@@ -1379,16 +1343,13 @@ def safeStringFormat(format_, params):
13791343 retVal = retVal .replace ("%s" , params )
13801344 else :
13811345 count , index = 0 , 0
1382-
13831346 while index != - 1 :
13841347 index = retVal .find ("%s" )
1385-
13861348 if index != - 1 :
13871349 if count < len (params ):
13881350 retVal = retVal [:index ] + getUnicode (params [count ]) + retVal [index + 2 :]
13891351 else :
13901352 raise sqlmapNoneDataException , "wrong number of parameters during string formatting"
1391-
13921353 count += 1
13931354
13941355 return retVal
@@ -1404,10 +1365,8 @@ def getFilteredPageContent(page, onlyText=True):
14041365 # only if the page's charset has been successfully identified
14051366 if isinstance (page , unicode ):
14061367 retVal = re .sub (r"(?si)<script.+?</script>|<!--.+?-->|<style.+?</style>%s" % (r"|<[^>]+>|\t|\n|\r" if onlyText else "" ), " " , page )
1407-
14081368 while retVal .find (" " ) != - 1 :
14091369 retVal = retVal .replace (" " , " " )
1410-
14111370 retVal = htmlunescape (retVal )
14121371
14131372 return retVal
@@ -1421,8 +1380,8 @@ def getPageWordSet(page):
14211380
14221381 # only if the page's charset has been successfully identified
14231382 if isinstance (page , unicode ):
1424- page = getFilteredPageContent (page )
1425- retVal = set (re .findall (r"\w+" , page ))
1383+ _ = getFilteredPageContent (page )
1384+ retVal = set (re .findall (r"\w+" , _ ))
14261385
14271386 return retVal
14281387
@@ -1557,8 +1516,8 @@ def getConsoleWidth(default=80):
15571516
15581517 width = None
15591518
1560- if 'COLUMNS' in os .environ and os . environ [ ' COLUMNS' ] .isdigit ():
1561- width = int (os .environ [ ' COLUMNS' ] )
1519+ if os .getenv ( " COLUMNS" , "" ) .isdigit ():
1520+ width = int (os .getenv ( " COLUMNS" ) )
15621521 else :
15631522 output = execute ('stty size' , shell = True , stdout = PIPE , stderr = PIPE ).stdout .read ()
15641523 items = output .split ()
@@ -1576,7 +1535,7 @@ def getConsoleWidth(default=80):
15761535 except :
15771536 pass
15781537
1579- return width if width else default
1538+ return width or default
15801539
15811540def clearConsoleLine (forceOutput = False ):
15821541 """
@@ -1591,7 +1550,7 @@ def parseXmlFile(xmlFile, handler):
15911550 Parses XML file by a given handler
15921551 """
15931552
1594- with StringIO (readCachedFileContent (xmlFile )) as stream :
1553+ with contextlib . closing ( StringIO (readCachedFileContent (xmlFile ) )) as stream :
15951554 parse (stream , handler )
15961555
15971556def getSPQLSnippet (dbms , name , ** variables ):
@@ -1632,8 +1591,7 @@ def readCachedFileContent(filename, mode='rb'):
16321591 if filename not in kb .cache .content :
16331592 checkFile (filename )
16341593 with codecs .open (filename , mode , UNICODE_ENCODING ) as f :
1635- content = f .read ()
1636- kb .cache .content [filename ] = content
1594+ kb .cache .content [filename ] = f .read ()
16371595
16381596 return kb .cache .content [filename ]
16391597
@@ -1675,12 +1633,7 @@ def average(values):
16751633 Computes the arithmetic mean of a list of numbers.
16761634 """
16771635
1678- retVal = None
1679-
1680- if values :
1681- retVal = sum (values ) / len (values )
1682-
1683- return retVal
1636+ return (sum (values ) / len (values )) if values else None
16841637
16851638def calculateDeltaSeconds (start ):
16861639 """
@@ -1891,8 +1844,8 @@ def getUnicode(value, encoding=None, system=False, noneToNull=False):
18911844def longestCommonPrefix (* sequences ):
18921845 """
18931846 Returns longest common prefix occuring in given sequences
1847+ Reference: http://boredzo.org/blog/archives/2007-01-06/longest-common-prefix-in-python-2
18941848 """
1895- # Reference: http://boredzo.org/blog/archives/2007-01-06/longest-common-prefix-in-python-2
18961849
18971850 if len (sequences ) == 1 :
18981851 return sequences [0 ]
@@ -2356,6 +2309,10 @@ def isInferenceAvailable():
23562309 return any (isTechniqueAvailable (_ ) for _ in (PAYLOAD .TECHNIQUE .BOOLEAN , PAYLOAD .TECHNIQUE .STACKED , PAYLOAD .TECHNIQUE .TIME ))
23572310
23582311def setOptimize ():
2312+ """
2313+ Sets options turned on by switch '-o'
2314+ """
2315+
23592316 #conf.predictOutput = True
23602317 conf .keepAlive = True
23612318 conf .threads = 3 if conf .threads < 3 else conf .threads
@@ -2719,7 +2676,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
27192676 parts = name .split ('.' )
27202677
27212678 for i in xrange (len (parts )):
2722- if not re .match (r"\A[A-Za-z0-9_@\$]+\Z" , parts [i ]): # reference : http://stackoverflow.com/questions/954884/what-special-characters-are-allowed-in-t-sql-column-name
2679+ if not re .match (r"\A[A-Za-z0-9_@\$]+\Z" , parts [i ]): # Reference : http://stackoverflow.com/questions/954884/what-special-characters-are-allowed-in-t-sql-column-name
27232680 if Backend .getIdentifiedDbms () in (DBMS .MYSQL , DBMS .ACCESS ):
27242681 parts [i ] = "`%s`" % parts [i ].strip ("`" )
27252682 elif Backend .getIdentifiedDbms () in (DBMS .ORACLE , DBMS .PGSQL , DBMS .DB2 ):
@@ -3082,10 +3039,7 @@ def unserializeObject(value):
30823039 Unserializes object from given serialized form
30833040 """
30843041
3085- retVal = None
3086- if value :
3087- retVal = base64unpickle (value )
3088- return retVal
3042+ return base64unpickle (value ) if value else None
30893043
30903044def resetCounter (technique ):
30913045 """
@@ -3176,10 +3130,7 @@ def extractExpectedValue(value, expected):
31763130 value = None
31773131 elif expected == EXPECTED .INT :
31783132 if isinstance (value , basestring ):
3179- if value .isdigit ():
3180- value = int (value )
3181- else :
3182- value = None
3133+ value = int (value ) if value .isdigit () else None
31833134
31843135 return value
31853136
@@ -3211,6 +3162,10 @@ def hashDBRetrieve(key, unserialize=False, checkConf=False):
32113162 return _
32123163
32133164def resetCookieJar (cookieJar ):
3165+ """
3166+ Cleans cookies from a given cookie jar
3167+ """
3168+
32143169 if not conf .loC :
32153170 cookieJar .clear ()
32163171 else :
@@ -3223,5 +3178,9 @@ def resetCookieJar(cookieJar):
32233178 raise sqlmapGenericException , errMsg
32243179
32253180def prioritySortColumns (columns ):
3181+ """
3182+ Sorts given column names by length in ascending order while those containing
3183+ string 'id' go first
3184+ """
32263185 _ = lambda x : x and "id" in x .lower ()
32273186 return sorted (sorted (columns , key = len ), lambda x , y : - 1 if _ (x ) and not _ (y ) else 1 if not _ (x ) and _ (y ) else 0 )
0 commit comments