4646from lib .core .exception import SqlmapMissingMandatoryOptionException
4747from lib .core .exception import SqlmapNoneDataException
4848from lib .core .exception import SqlmapUserQuitException
49+ from lib .core .settings import BINARY_FIELDS_TYPE_KEYWORDS
4950from lib .core .settings import CURRENT_DB
5051from lib .core .settings import METADB_SUFFIX
5152from lib .core .settings import PLUS_ONE_DBMSES
@@ -931,7 +932,16 @@ def columnNameQuery(index):
931932 warnMsg += "possible to get column comments"
932933 singleTimeWarnMessage (warnMsg )
933934
934- if not onlyColNames :
935+ # In dump mode we don't need the exact type, only whether the column is binary (so its raw
936+ # bytes get hex-extracted instead of mangled/truncated - issues #8/#582/#2827). Rather than
937+ # extract the whole type string char-by-char, wrap the type query into a single-bit check and
938+ # extract just that (~10x fewer requests). Skipped where query2 doesn't yield a type name:
939+ # MSSQL (returns the column name), Firebird/Informix (numeric type codes), and PostgreSQL
940+ # (its bytea already renders fine, so it's excluded from auto-hexing anyway).
941+ binaryProbe = onlyColNames and dumpMode and not Backend .getIdentifiedDbms () in (DBMS .MSSQL , DBMS .PGSQL , DBMS .FIREBIRD , DBMS .INFORMIX )
942+
943+ if not onlyColNames or binaryProbe :
944+ query = None
935945 if Backend .getIdentifiedDbms () in (DBMS .MYSQL , DBMS .PGSQL , DBMS .HSQLDB , DBMS .H2 , DBMS .VERTICA , DBMS .PRESTO , DBMS .CRATEDB , DBMS .CACHE , DBMS .FRONTBASE , DBMS .VIRTUOSO , DBMS .CLICKHOUSE ):
936946 query = rootQuery .blind .query2 % (unsafeSQLIdentificatorNaming (tbl ), column , unsafeSQLIdentificatorNaming (conf .db ))
937947 elif Backend .getIdentifiedDbms () in (DBMS .ORACLE , DBMS .DB2 , DBMS .DERBY , DBMS .ALTIBASE , DBMS .MIMERSQL ):
@@ -947,22 +957,35 @@ def columnNameQuery(index):
947957 elif Backend .isDbms (DBMS .SPANNER ):
948958 query = rootQuery .blind .query2 % (unsafeSQLIdentificatorNaming (tbl ), column , unsafeSQLIdentificatorNaming (conf .db ), unsafeSQLIdentificatorNaming (conf .db ))
949959
950- colType = unArrayizeValue (inject .getValue (query , union = False , error = False ))
951- key = int (colType ) if hasattr (colType , "isdigit" ) and colType .isdigit () else colType
960+ if binaryProbe and query :
961+ typeMatch = re .match (r"(?is)\s*SELECT\s+(.+?)\s+FROM\s+(.+)" , query )
962+ if typeMatch :
963+ binaryCondition = " OR " .join ("UPPER(%s) LIKE '%%%s%%'" % (typeMatch .group (1 ), _ ) for _ in BINARY_FIELDS_TYPE_KEYWORDS )
964+ query = "SELECT (CASE WHEN %s THEN 1 ELSE 0 END) FROM %s" % (binaryCondition , typeMatch .group (2 ))
965+ else :
966+ query = None # unexpected shape - fall back to leaving the type unknown
952967
953- if Backend .isDbms (DBMS .FIREBIRD ):
954- colType = FIREBIRD_TYPES .get (key , colType )
955- elif Backend .isDbms (DBMS .INFORMIX ):
956- notNull = False
957- if isinstance (key , int ) and key > 255 :
958- key -= 256
959- notNull = True
960- colType = INFORMIX_TYPES .get (key , colType )
961- if notNull :
962- colType = "%s NOT NULL" % colType
968+ colType = unArrayizeValue (inject .getValue (query , union = False , error = False )) if query else None
963969
964- column = safeSQLIdentificatorNaming (column )
965- columns [column ] = colType
970+ if binaryProbe :
971+ column = safeSQLIdentificatorNaming (column )
972+ columns [column ] = "binary" if colType in ('1' , 1 ) else None # sentinel matched by BINARY_FIELDS_TYPE_REGEX
973+ else :
974+ key = int (colType ) if hasattr (colType , "isdigit" ) and colType .isdigit () else colType
975+
976+ if Backend .isDbms (DBMS .FIREBIRD ):
977+ colType = FIREBIRD_TYPES .get (key , colType )
978+ elif Backend .isDbms (DBMS .INFORMIX ):
979+ notNull = False
980+ if isinstance (key , int ) and key > 255 :
981+ key -= 256
982+ notNull = True
983+ colType = INFORMIX_TYPES .get (key , colType )
984+ if notNull :
985+ colType = "%s NOT NULL" % colType
986+
987+ column = safeSQLIdentificatorNaming (column )
988+ columns [column ] = colType
966989 else :
967990 column = safeSQLIdentificatorNaming (column )
968991 columns [column ] = None
0 commit comments