diff --git a/lib/core/agent.py b/lib/core/agent.py
index c97401f62..f9b72b397 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -675,6 +675,71 @@ class Agent(object):
return unionQuery
+ def limitCondition(self, expression, dump=False):
+ startLimit = 0
+ stopLimit = None
+ limitCond = True
+
+ limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
+ limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
+ topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
+
+ if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
+ limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
+ limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
+
+ if limitGroupStart.isdigit():
+ if limitRegExp:
+ startLimit = int(limitRegExp.group(int(limitGroupStart)))
+ stopLimit = limitRegExp.group(int(limitGroupStop))
+ elif limitRegExp2:
+ startLimit = 0
+ stopLimit = limitRegExp2.group(int(limitGroupStart))
+ limitCond = int(stopLimit) > 1
+
+ elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
+ if limitRegExp:
+ limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
+ limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
+
+ if limitGroupStart.isdigit():
+ startLimit = int(limitRegExp.group(int(limitGroupStart)))
+
+ stopLimit = limitRegExp.group(int(limitGroupStop))
+ limitCond = int(stopLimit) > 1
+ elif topLimit:
+ startLimit = 0
+ stopLimit = int(topLimit.group(1))
+ limitCond = int(stopLimit) > 1
+
+ elif Backend.isDbms(DBMS.ORACLE):
+ limitCond = False
+
+ # We assume that only queries NOT containing a "LIMIT #, 1"
+ # (or equivalent depending on the back-end DBMS) can return
+ # multiple entries
+ if limitCond:
+ if (limitRegExp or limitRegExp2) and stopLimit is not None:
+ stopLimit = int(stopLimit)
+
+ # From now on we need only the expression until the " LIMIT "
+ # (or equivalent, depending on the back-end DBMS) word
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
+ stopLimit += startLimit
+ _ = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
+ expression = expression[:_]
+
+ elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
+ stopLimit += startLimit
+ elif dump:
+ if conf.limitStart:
+ startLimit = conf.limitStart - 1
+ if conf.limitStop:
+ stopLimit = conf.limitStop
+
+ return expression, limitCond, topLimit, startLimit, stopLimit
+
def limitQuery(self, num, query, field=None, uniqueField=None):
"""
Take in input a query string and return its limited query string.
diff --git a/lib/core/common.py b/lib/core/common.py
index fe23b0f18..56a838875 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -661,6 +661,9 @@ def filePathToString(filePath):
return strRepl
+def singleTimeDebugMessage(message):
+ singleTimeLogMessage(message, logging.DEBUG)
+
def singleTimeWarnMessage(message):
singleTimeLogMessage(message, logging.WARN)
diff --git a/lib/core/testing.py b/lib/core/testing.py
index 1dc9337ff..fdb036530 100644
--- a/lib/core/testing.py
+++ b/lib/core/testing.py
@@ -129,7 +129,7 @@ def liveTest():
if case.hasAttribute("name"):
name = case.getAttribute("name")
- if conf.runCase and ((conf.runCase.isdigit() and conf.runCase != count) or not re.search(conf.runCase, name, re.DOTALL)):
+ if conf.runCase and ((conf.runCase.isdigit() and conf.runCase != count) or not re.search(conf.runCase, name, re.DOTALL | re.I)):
continue
if case.getElementsByTagName("switches"):
@@ -206,7 +206,7 @@ def runCase(switches=None, parse=None):
retVal = False
if parse and retVal:
- ifile = open(conf.dumper.getOutputFile(), 'r')
+ ifile = open(conf.dumper.getOutputFile(), "rb")
content = ifile.read()
ifile.close()
for item in parse:
diff --git a/lib/request/inject.py b/lib/request/inject.py
index 82dae2431..bab81c138 100644
--- a/lib/request/inject.py
+++ b/lib/request/inject.py
@@ -139,8 +139,6 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
startLimit = 0
stopLimit = None
outputs = BigArray()
- untilLimitChar = None
- untilOrderChar = None
if not unpack:
return _goInference(payload, expression, charsetType, firstChar, lastChar, dump)
@@ -160,69 +158,18 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
# If we have been here from SQL query/shell we have to check if
# the SQL query might return multiple entries and in such case
- # forge the SQL limiting the query output one entry per time
- # NOTE: I assume that only queries that get data from a table
+ # forge the SQL limiting the query output one entry at a time
+ # NOTE: we assume that only queries that get data from a table
# can return multiple entries
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() \
not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not \
expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
+ expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression)
- limitCond = True
- limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
- limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
- topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
-
- if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
- limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
- limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
-
- if limitGroupStart.isdigit():
- if limitRegExp2:
- startLimit = 0
- stopLimit = limitRegExp2.group(int(limitGroupStart))
- else:
- startLimit = int(limitRegExp.group(int(limitGroupStart)))
- stopLimit = limitRegExp.group(int(limitGroupStop))
- limitCond = int(stopLimit) > 1
-
- elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
- if limitRegExp:
- limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
- limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
-
- if limitGroupStart.isdigit():
- startLimit = int(limitRegExp.group(int(limitGroupStart)))
-
- stopLimit = limitRegExp.group(int(limitGroupStop))
- limitCond = int(stopLimit) > 1
- elif topLimit:
- startLimit = 0
- stopLimit = int(topLimit.group(1))
- limitCond = int(stopLimit) > 1
-
- elif Backend.isDbms(DBMS.ORACLE):
- limitCond = False
-
- # We assume that only queries NOT containing a "LIMIT #, 1"
- # (or equivalent depending on the back-end DBMS) can return
- # multiple entries
if limitCond:
- if (limitRegExp or limitRegExp2) and stopLimit is not None:
- stopLimit = int(stopLimit)
-
- # From now on we need only the expression until the " LIMIT "
- # (or equivalent, depending on the back-end DBMS) word
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
- stopLimit += startLimit
- untilLimitChar = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
- expression = expression[:untilLimitChar]
-
- elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
- stopLimit += startLimit
-
test = True
+
if not stopLimit or stopLimit <= 1:
if Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]):
test = False
@@ -232,9 +179,9 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
countFirstField = queries[Backend.getIdentifiedDbms()].count.query % expressionFieldsList[0]
countedExpression = expression.replace(expressionFields, countFirstField, 1)
- if re.search(" ORDER BY ", expression, re.I):
- untilOrderChar = countedExpression.index(" ORDER BY ")
- countedExpression = countedExpression[:untilOrderChar]
+ if " ORDER BY " in expression.upper():
+ _ = countedExpression.upper().rindex(" ORDER BY ")
+ countedExpression = countedExpression[:_]
if not stopLimit:
count = _goInference(payload, countedExpression, charsetType=CHARSET_TYPE.DIGITS, firstChar=firstChar, lastChar=lastChar)
diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py
index 7c997665d..4d2e9e4d8 100644
--- a/lib/techniques/error/use.py
+++ b/lib/techniques/error/use.py
@@ -238,14 +238,13 @@ def errorUse(expression, dump=False):
stopLimit = None
output = None
outputs = None
- untilLimitChar = None
_, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(expression)
# We have to check if the SQL query might return multiple entries
# and in such case forge the SQL limiting the query output one
- # entry per time
- # NOTE: I assume that only queries that get data from a table can
+ # entry at a time
+ # NOTE: we assume that only queries that get data from a table can
# return multiple entries
if (dump and (conf.limitStart or conf.limitStop)) or (" FROM " in \
expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) \
@@ -253,70 +252,13 @@ def errorUse(expression, dump=False):
expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
and ("(CASE" not in expression.upper() or ("(CASE" in expression.upper() and "WHEN use" in expression))) \
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
+ expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
- limitCond = True
- limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
- limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
- topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
-
- if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
- limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
- limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
-
- if limitGroupStart.isdigit():
- if limitRegExp2:
- startLimit = 0
- stopLimit = limitRegExp2.group(int(limitGroupStart))
- else:
- startLimit = int(limitRegExp.group(int(limitGroupStart)))
- stopLimit = limitRegExp.group(int(limitGroupStop))
- limitCond = int(stopLimit) > 1
-
- elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
- if limitRegExp:
- limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
- limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
-
- if limitGroupStart.isdigit():
- startLimit = int(limitRegExp.group(int(limitGroupStart)))
-
- stopLimit = limitRegExp.group(int(limitGroupStop))
- limitCond = int(stopLimit) > 1
- elif topLimit:
- startLimit = 0
- stopLimit = int(topLimit.group(1))
- limitCond = int(stopLimit) > 1
-
- elif Backend.isDbms(DBMS.ORACLE):
- limitCond = False
-
- # I assume that only queries NOT containing a "LIMIT #, 1"
- # (or equivalent depending on the back-end DBMS) can return
- # multiple entries
if limitCond:
- if (limitRegExp or limitRegExp2) and stopLimit is not None:
- stopLimit = int(stopLimit)
-
- # From now on we need only the expression until the " LIMIT "
- # (or equivalent, depending on the back-end DBMS) word
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
- stopLimit += startLimit
- untilLimitChar = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
- expression = expression[:untilLimitChar]
-
- elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
- stopLimit += startLimit
- elif dump:
- if conf.limitStart:
- startLimit = conf.limitStart - 1
- if conf.limitStop:
- stopLimit = conf.limitStop
-
# Count the number of SQL query entries output
countedExpression = expression.replace(expressionFields, queries[Backend.getIdentifiedDbms()].count.query % ('*' if len(expressionFieldsList) > 1 else expressionFields), 1)
- if " ORDER BY " in expression:
+ if " ORDER BY " in expression.upper():
_ = countedExpression.upper().rindex(" ORDER BY ")
countedExpression = countedExpression[:_]
diff --git a/lib/techniques/union/use.py b/lib/techniques/union/use.py
index 0512972c7..85e810fd1 100644
--- a/lib/techniques/union/use.py
+++ b/lib/techniques/union/use.py
@@ -29,6 +29,7 @@ from lib.core.common import isNumPosStrValue
from lib.core.common import listToStrValue
from lib.core.common import parseUnionPage
from lib.core.common import removeReflectiveValues
+from lib.core.common import singleTimeDebugMessage
from lib.core.common import singleTimeWarnMessage
from lib.core.common import wasLastRequestDBMSError
from lib.core.convert import htmlunescape
@@ -159,14 +160,17 @@ def unionUse(expression, unpack=True, dump=False):
_, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(origExpr)
- if expressionFieldsList and len(expressionFieldsList) > 1 and " ORDER BY " in expression.upper():
- # No need for it in multicolumn dumps (one row is retrieved per request) and just slowing down on large table dumps
- expression = expression[:expression.upper().rindex(" ORDER BY ")]
+ if expressionFieldsList and len(expressionFieldsList) > 1 and "ORDER BY" in expression.upper():
+ # Removed ORDER BY clause because UNION does not play well with it
+ expression = re.sub("\s*ORDER BY\s+[\w,]+", "", expression, re.I)
+ debugMsg = "stripping ORDER BY clause from statement because "
+ debugMsg += "it does not play well with UNION query SQL injection"
+ singleTimeDebugMessage(debugMsg)
# We have to check if the SQL query might return multiple entries
- # and in such case forge the SQL limiting the query output one
- # entry per time
- # NOTE: I assume that only queries that get data from a table can
+ # if the technique is partial UNION query and in such case forge the
+ # SQL limiting the query output one entry at a time
+ # NOTE: we assume that only queries that get data from a table can
# return multiple entries
if (kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.NEGATIVE or \
(dump and (conf.limitStart or conf.limitStop))) and \
@@ -174,66 +178,9 @@ def unionUse(expression, unpack=True, dump=False):
not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE \
and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
+ expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
- limitCond = True
- limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
- limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
- topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
-
- if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
- limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
- limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
-
- if limitGroupStart.isdigit():
- if limitRegExp2:
- startLimit = 0
- stopLimit = limitRegExp2.group(int(limitGroupStart))
- else:
- startLimit = int(limitRegExp.group(int(limitGroupStart)))
- stopLimit = limitRegExp.group(int(limitGroupStop))
- limitCond = int(stopLimit) > 1
-
- elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
- if limitRegExp:
- limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
- limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
-
- if limitGroupStart.isdigit():
- startLimit = int(limitRegExp.group(int(limitGroupStart)))
-
- stopLimit = limitRegExp.group(int(limitGroupStop))
- limitCond = int(stopLimit) > 1
- elif topLimit:
- startLimit = 0
- stopLimit = int(topLimit.group(1))
- limitCond = int(stopLimit) > 1
-
- elif Backend.isDbms(DBMS.ORACLE):
- limitCond = False
-
- # I assume that only queries NOT containing a "LIMIT #, 1"
- # (or equivalent depending on the back-end DBMS) can return
- # multiple entries
if limitCond:
- if (limitRegExp or limitRegExp2) and stopLimit is not None:
- stopLimit = int(stopLimit)
-
- # From now on we need only the expression until the " LIMIT "
- # (or equivalent, depending on the back-end DBMS) word
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
- stopLimit += startLimit
- untilLimitChar = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
- expression = expression[:untilLimitChar]
-
- elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
- stopLimit += startLimit
- elif dump:
- if conf.limitStart:
- startLimit = conf.limitStart - 1
- if conf.limitStop:
- stopLimit = conf.limitStop
-
# Count the number of SQL query entries output
countedExpression = expression.replace(expressionFields, queries[Backend.getIdentifiedDbms()].count.query % ('*' if len(expressionFieldsList) > 1 else expressionFields), 1)
@@ -362,7 +309,6 @@ def unionUse(expression, unpack=True, dump=False):
kb.suppressResumeInfo = False
if not value and not abortedFlag:
- expression = re.sub("\s*ORDER BY\s+[\w,]+", "", expression, re.I) # full union doesn't play well with ORDER BY
value = _oneShotUnionUse(expression, unpack)
duration = calculateDeltaSeconds(start)
diff --git a/thirdparty/magic/magic.py b/thirdparty/magic/magic.py
index 9df32a108..08a4e0633 100644
--- a/thirdparty/magic/magic.py
+++ b/thirdparty/magic/magic.py
@@ -106,99 +106,100 @@ def from_buffer(buffer, mime=False):
+try:
+ libmagic = None
+ # Let's try to find magic or magic1
+ dll = ctypes.util.find_library('magic') or ctypes.util.find_library('magic1')
-libmagic = None
-# Let's try to find magic or magic1
-dll = ctypes.util.find_library('magic') or ctypes.util.find_library('magic1')
+ # This is necessary because find_library returns None if it doesn't find the library
+ if dll:
+ libmagic = ctypes.CDLL(dll)
-# This is necessary because find_library returns None if it doesn't find the library
-if dll:
- libmagic = ctypes.CDLL(dll)
+ if not libmagic or not libmagic._name:
+ import sys
+ platform_to_lib = {'darwin': ['/opt/local/lib/libmagic.dylib',
+ '/usr/local/lib/libmagic.dylib',
+ '/usr/local/Cellar/libmagic/5.10/lib/libmagic.dylib'],
+ 'win32': ['magic1.dll']}
+ for dll in platform_to_lib.get(sys.platform, []):
+ try:
+ libmagic = ctypes.CDLL(dll)
+ except OSError:
+ pass
-if not libmagic or not libmagic._name:
- import sys
- platform_to_lib = {'darwin': ['/opt/local/lib/libmagic.dylib',
- '/usr/local/lib/libmagic.dylib',
- '/usr/local/Cellar/libmagic/5.10/lib/libmagic.dylib'],
- 'win32': ['magic1.dll']}
- for dll in platform_to_lib.get(sys.platform, []):
- try:
- libmagic = ctypes.CDLL(dll)
- except OSError:
- pass
+ if not libmagic or not libmagic._name:
+ # It is better to raise an ImportError since we are importing magic module
+ raise ImportError('failed to find libmagic. Check your installation')
-if not libmagic or not libmagic._name:
- # It is better to raise an ImportError since we are importing magic module
- raise ImportError('failed to find libmagic. Check your installation')
+ magic_t = ctypes.c_void_p
-magic_t = ctypes.c_void_p
+ def errorcheck(result, func, args):
+ err = magic_error(args[0])
+ if err is not None:
+ raise MagicException(err)
+ else:
+ return result
-def errorcheck(result, func, args):
- err = magic_error(args[0])
- if err is not None:
- raise MagicException(err)
- else:
- return result
+ def coerce_filename(filename):
+ if filename is None:
+ return None
+ return filename.encode(sys.getfilesystemencoding())
-def coerce_filename(filename):
- if filename is None:
- return None
- return filename.encode(sys.getfilesystemencoding())
+ magic_open = libmagic.magic_open
+ magic_open.restype = magic_t
+ magic_open.argtypes = [c_int]
-magic_open = libmagic.magic_open
-magic_open.restype = magic_t
-magic_open.argtypes = [c_int]
+ magic_close = libmagic.magic_close
+ magic_close.restype = None
+ magic_close.argtypes = [magic_t]
-magic_close = libmagic.magic_close
-magic_close.restype = None
-magic_close.argtypes = [magic_t]
+ magic_error = libmagic.magic_error
+ magic_error.restype = c_char_p
+ magic_error.argtypes = [magic_t]
-magic_error = libmagic.magic_error
-magic_error.restype = c_char_p
-magic_error.argtypes = [magic_t]
+ magic_errno = libmagic.magic_errno
+ magic_errno.restype = c_int
+ magic_errno.argtypes = [magic_t]
-magic_errno = libmagic.magic_errno
-magic_errno.restype = c_int
-magic_errno.argtypes = [magic_t]
+ _magic_file = libmagic.magic_file
+ _magic_file.restype = c_char_p
+ _magic_file.argtypes = [magic_t, c_char_p]
+ _magic_file.errcheck = errorcheck
-_magic_file = libmagic.magic_file
-_magic_file.restype = c_char_p
-_magic_file.argtypes = [magic_t, c_char_p]
-_magic_file.errcheck = errorcheck
+ def magic_file(cookie, filename):
+ return _magic_file(cookie, coerce_filename(filename))
-def magic_file(cookie, filename):
- return _magic_file(cookie, coerce_filename(filename))
-
-_magic_buffer = libmagic.magic_buffer
-_magic_buffer.restype = c_char_p
-_magic_buffer.argtypes = [magic_t, c_void_p, c_size_t]
-_magic_buffer.errcheck = errorcheck
+ _magic_buffer = libmagic.magic_buffer
+ _magic_buffer.restype = c_char_p
+ _magic_buffer.argtypes = [magic_t, c_void_p, c_size_t]
+ _magic_buffer.errcheck = errorcheck
-def magic_buffer(cookie, buf):
- return _magic_buffer(cookie, buf, len(buf))
+ def magic_buffer(cookie, buf):
+ return _magic_buffer(cookie, buf, len(buf))
-_magic_load = libmagic.magic_load
-_magic_load.restype = c_int
-_magic_load.argtypes = [magic_t, c_char_p]
-_magic_load.errcheck = errorcheck
+ _magic_load = libmagic.magic_load
+ _magic_load.restype = c_int
+ _magic_load.argtypes = [magic_t, c_char_p]
+ _magic_load.errcheck = errorcheck
-def magic_load(cookie, filename):
- return _magic_load(cookie, coerce_filename(filename))
+ def magic_load(cookie, filename):
+ return _magic_load(cookie, coerce_filename(filename))
-magic_setflags = libmagic.magic_setflags
-magic_setflags.restype = c_int
-magic_setflags.argtypes = [magic_t, c_int]
+ magic_setflags = libmagic.magic_setflags
+ magic_setflags.restype = c_int
+ magic_setflags.argtypes = [magic_t, c_int]
-magic_check = libmagic.magic_check
-magic_check.restype = c_int
-magic_check.argtypes = [magic_t, c_char_p]
-
-magic_compile = libmagic.magic_compile
-magic_compile.restype = c_int
-magic_compile.argtypes = [magic_t, c_char_p]
+ magic_check = libmagic.magic_check
+ magic_check.restype = c_int
+ magic_check.argtypes = [magic_t, c_char_p]
+ magic_compile = libmagic.magic_compile
+ magic_compile.restype = c_int
+ magic_compile.argtypes = [magic_t, c_char_p]
+except ImportError:
+ pass
MAGIC_NONE = 0x000000 # No flags
diff --git a/xml/livetests.xml b/xml/livetests.xml
index 8393d0022..2ffa01e19 100644
--- a/xml/livetests.xml
+++ b/xml/livetests.xml
@@ -44,7 +44,7 @@
-
+
@@ -87,7 +87,7 @@
-
+
@@ -130,7 +130,7 @@
-
+
@@ -173,7 +173,7 @@
-
+
@@ -190,18 +190,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -211,15 +199,6 @@
-
-
-
-
-
-
-
-
-
@@ -259,7 +238,7 @@
-
+
@@ -304,11 +283,14 @@
-
+
+
+
@@ -366,7 +348,7 @@
-
+
@@ -380,7 +362,7 @@
-
+
@@ -394,7 +376,7 @@
-
+
@@ -653,400 +635,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-