6363from lib .core .data import kb
6464from lib .core .data import logger
6565from lib .core .data import paths
66+ from lib .core .datatype import OrderedSet
6667from lib .core .decorators import cachedmethod
6768from lib .core .defaults import defaults
6869from lib .core .dicts import DBMS_DICT
@@ -843,7 +844,15 @@ def getManualDirectories():
843844 return directories
844845
845846def getAutoDirectories ():
846- retVal = set ()
847+ """
848+ >>> pushValue(kb.absFilePaths)
849+ >>> kb.absFilePaths = ["C:\\ inetpub\\ wwwroot\\ index.asp", "/var/www/html"]
850+ >>> getAutoDirectories()
851+ ['C:/inetpub/wwwroot', '/var/www/html']
852+ >>> kb.absFilePaths = popValue()
853+ """
854+
855+ retVal = OrderedSet ()
847856
848857 if kb .absFilePaths :
849858 infoMsg = "retrieved web server absolute paths: "
@@ -1370,7 +1379,16 @@ def weAreFrozen():
13701379
13711380def parseTargetDirect ():
13721381 """
1373- Parse target dbms and set some attributes into the configuration singleton.
1382+ Parse target dbms and set some attributes into the configuration singleton
1383+
1384+ >>> pushValue(conf.direct)
1385+ >>> conf.direct = "mysql://root:[email protected] :3306/testdb" 1386+ >>> parseTargetDirect()
1387+ >>> conf.dbmsDb
1388+ 'testdb'
1389+ >>> conf.dbmsPass
1390+ 'testpass'
1391+ >>> conf.direct = popValue()
13741392 """
13751393
13761394 if not conf .direct :
@@ -1411,6 +1429,9 @@ def parseTargetDirect():
14111429
14121430 break
14131431
1432+ if kb .smokeMode :
1433+ return
1434+
14141435 if not details :
14151436 errMsg = "invalid target details, valid syntax is for instance "
14161437 errMsg += "'mysql://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME' "
@@ -1475,7 +1496,16 @@ def parseTargetDirect():
14751496
14761497def parseTargetUrl ():
14771498 """
1478- Parse target URL and set some attributes into the configuration singleton.
1499+ Parse target URL and set some attributes into the configuration singleton
1500+
1501+ >>> pushValue(conf.url)
1502+ >>> conf.url = "https://www.test.com/?id=1"
1503+ >>> parseTargetUrl()
1504+ >>> conf.hostname
1505+ 'www.test.com'
1506+ >>> conf.scheme
1507+ 'https'
1508+ >>> conf.url = popValue()
14791509 """
14801510
14811511 if not conf .url :
@@ -1826,11 +1856,13 @@ def directoryPath(filepath):
18261856
18271857 >>> directoryPath('/var/log/apache.log')
18281858 '/var/log'
1859+ >>> directoryPath('/var/log')
1860+ '/var/log'
18291861 """
18301862
18311863 retVal = filepath
18321864
1833- if filepath :
1865+ if filepath and os . path . splitext ( filepath )[ - 1 ] :
18341866 retVal = ntpath .dirname (filepath ) if isWindowsDriveLetterPath (filepath ) else posixpath .dirname (filepath )
18351867
18361868 return retVal
@@ -3029,8 +3061,7 @@ def filterNone(values):
30293061
30303062def isDBMSVersionAtLeast (version ):
30313063 """
3032- Checks if the recognized DBMS version is at least the version
3033- specified
3064+ Checks if the recognized DBMS version is at least the version specified
30343065 """
30353066
30363067 retVal = None
@@ -3065,6 +3096,12 @@ def isDBMSVersionAtLeast(version):
30653096def parseSqliteTableSchema (value ):
30663097 """
30673098 Parses table column names and types from specified SQLite table schema
3099+
3100+ >>> kb.data.cachedColumns = {}
3101+ >>> parseSqliteTableSchema("CREATE TABLE users\\ n\\ t\\ tid INTEGER\\ n\\ t\\ tname TEXT\\ n);")
3102+ True
3103+ >>> repr(kb.data.cachedColumns).count(',') == 1
3104+ True
30683105 """
30693106
30703107 retVal = False
@@ -3091,8 +3128,13 @@ def getTechniqueData(technique=None):
30913128
30923129def isTechniqueAvailable (technique ):
30933130 """
3094- Returns True if there is injection data which sqlmap could use for
3095- technique specified
3131+ Returns True if there is injection data which sqlmap could use for technique specified
3132+
3133+ >>> pushValue(kb.injection.data)
3134+ >>> kb.injection.data[PAYLOAD.TECHNIQUE.ERROR] = [test for test in getSortedInjectionTests() if "error" in test["title"].lower()][0]
3135+ >>> isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR)
3136+ True
3137+ >>> kb.injection.data = popValue()
30963138 """
30973139
30983140 if conf .tech and isinstance (conf .tech , list ) and technique not in conf .tech :
@@ -3103,6 +3145,12 @@ def isTechniqueAvailable(technique):
31033145def isStackingAvailable ():
31043146 """
31053147 Returns True whether techniques using stacking are available
3148+
3149+ >>> pushValue(kb.injection.data)
3150+ >>> kb.injection.data[PAYLOAD.TECHNIQUE.STACKED] = [test for test in getSortedInjectionTests() if "stacked" in test["title"].lower()][0]
3151+ >>> isStackingAvailable()
3152+ True
3153+ >>> kb.injection.data = popValue()
31063154 """
31073155
31083156 retVal = False
@@ -3121,6 +3169,12 @@ def isStackingAvailable():
31213169def isInferenceAvailable ():
31223170 """
31233171 Returns True whether techniques using inference technique are available
3172+
3173+ >>> pushValue(kb.injection.data)
3174+ >>> kb.injection.data[PAYLOAD.TECHNIQUE.BOOLEAN] = getSortedInjectionTests()[0]
3175+ >>> isInferenceAvailable()
3176+ True
3177+ >>> kb.injection.data = popValue()
31243178 """
31253179
31263180 return any (isTechniqueAvailable (_ ) for _ in (PAYLOAD .TECHNIQUE .BOOLEAN , PAYLOAD .TECHNIQUE .STACKED , PAYLOAD .TECHNIQUE .TIME ))
@@ -3290,8 +3344,13 @@ def isListLike(value):
32903344
32913345def getSortedInjectionTests ():
32923346 """
3293- Returns prioritized test list by eventually detected DBMS from error
3294- messages
3347+ Returns prioritized test list by eventually detected DBMS from error messages
3348+
3349+ >>> pushValue(kb.forcedDbms)
3350+ >>> kb.forcedDbms = DBMS.SQLITE
3351+ >>> [test for test in getSortedInjectionTests() if hasattr(test, "details") and hasattr(test.details, "dbms")][0].details.dbms == kb.forcedDbms
3352+ True
3353+ >>> kb.forcedDbms = popValue()
32953354 """
32963355
32973356 retVal = copy .deepcopy (conf .tests )
@@ -3317,8 +3376,7 @@ def priorityFunction(test):
33173376
33183377def filterListValue (value , regex ):
33193378 """
3320- Returns list with items that have parts satisfying given regular
3321- expression
3379+ Returns list with items that have parts satisfying given regular expression
33223380
33233381 >>> filterListValue(['users', 'admins', 'logs'], r'(users|admins)')
33243382 ['users', 'admins']
@@ -3348,6 +3406,9 @@ def showHttpErrorCodes():
33483406def openFile (filename , mode = 'r' , encoding = UNICODE_ENCODING , errors = "reversible" , buffering = 1 ): # "buffering=1" means line buffered (Reference: http://stackoverflow.com/a/3168436)
33493407 """
33503408 Returns file handle of a given filename
3409+
3410+ >>> "openFile" in openFile(__file__).read()
3411+ True
33513412 """
33523413
33533414 if filename == STDIN_PIPE_DASH :
@@ -3399,22 +3460,6 @@ def decodeIntToUnicode(value):
33993460
34003461 return retVal
34013462
3402- def md5File (filename ):
3403- """
3404- Calculates MD5 digest of a file
3405-
3406- # Reference: http://stackoverflow.com/a/3431838
3407- """
3408-
3409- checkFile (filename )
3410-
3411- digest = hashlib .md5 ()
3412- with open (filename , "rb" ) as f :
3413- for chunk in iter (lambda : f .read (4096 ), "" ):
3414- digest .update (chunk )
3415-
3416- return digest .hexdigest ()
3417-
34183463def checkIntegrity ():
34193464 """
34203465 Checks integrity of code files during the unhandled exceptions
@@ -3441,6 +3486,9 @@ def checkIntegrity():
34413486def getDaysFromLastUpdate ():
34423487 """
34433488 Get total number of days from last update
3489+
3490+ >>> getDaysFromLastUpdate() >= 0
3491+ True
34443492 """
34453493
34463494 if not paths :
@@ -3451,6 +3499,9 @@ def getDaysFromLastUpdate():
34513499def unhandledExceptionMessage ():
34523500 """
34533501 Returns detailed message about occurred unhandled exception
3502+
3503+ >>> all(_ in unhandledExceptionMessage() for _ in ("unhandled exception occurred", "Operating system", "Command line"))
3504+ True
34543505 """
34553506
34563507 errMsg = "unhandled exception occurred in %s. It is recommended to retry your " % VERSION_STRING
0 commit comments