You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sqlmap/src/sqlmap-master/thirdparty/ansistrm/ansistrm.py

195 lines
6.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#
# Copyright (C) 2010-2012 Vinay Sajip. All rights reserved. Licensed under the new BSD license.
# (Note: 2018 modifications by @stamparm)
#
import logging
import re
import sys
from lib.core.settings import IS_WIN # 导入一个设置用于判断是否在Windows系统上运行
if IS_WIN:
import ctypes
import ctypes.wintypes
# Reference: https://gist.github.com/vsajip/758430
# https://github.com/ipython/ipython/issues/4252
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms686047%28v=vs.85%29.aspx
# 设置Windows API函数SetConsoleTextAttribute的参数和返回值类型
ctypes.windll.kernel32.SetConsoleTextAttribute.argtypes = [ctypes.wintypes.HANDLE, ctypes.wintypes.WORD]
ctypes.windll.kernel32.SetConsoleTextAttribute.restype = ctypes.wintypes.BOOL
def stdoutEncode(data): # 用于编码标准输出数据的函数
return data
class ColorizingStreamHandler(logging.StreamHandler):
# 定义颜色名称到索引的映射
color_map = {
'black': 0,
'red': 1,
'green': 2,
'yellow': 3,
'blue': 4,
'magenta': 5,
'cyan': 6,
'white': 7,
}
# 定义日志级别到颜色和样式的映射
level_map = {
logging.DEBUG: (None, 'blue', False),
logging.INFO: (None, 'green', False),
logging.WARNING: (None, 'yellow', False),
logging.ERROR: (None, 'red', False),
logging.CRITICAL: ('red', 'white', False)
}
csi = '\x1b[' # ANSI转义序列的前缀
reset = '\x1b[0m' # ANSI重置颜色的转义序列
bold = "\x1b[1m" # ANSI加粗的转义序列
disable_coloring = False # 是否禁用颜色
@property
def is_tty(self):
# 检查流是否是终端
isatty = getattr(self.stream, 'isatty', None)
return isatty and isatty() and not self.disable_coloring
def emit(self, record):
# 发送日志记录
try:
message = stdoutEncode(self.format(record))
stream = self.stream
#如果当前流不是TTY直接写入消息
if not self.is_tty:
if message and message[0] == "\r":
message = message[1:]
stream.write(message)
#如果是TTY调用output_colorized方法来输出带颜色的消息
else:
self.output_colorized(message)
stream.write(getattr(self, 'terminator', '\n'))
self.flush()
except (KeyboardInterrupt, SystemExit):
raise
except IOError:
#IO错误时什么也不做pass
pass
except:
#其他异常时调用handleError方法
self.handleError(record)
if not IS_WIN:
def output_colorized(self, message):
# 如果不是Windows系统直接写入消息
self.stream.write(message)
else:
ansi_esc = re.compile(r'\x1b\[((?:\d+)(?:;(?:\d+))*)m')
# 正则表达式用于匹配ANSI转义序列
nt_color_map = {
0: 0x00, # black
1: 0x04, # red
2: 0x02, # green
3: 0x06, # yellow
4: 0x01, # blue
5: 0x05, # magenta
6: 0x03, # cyan
7: 0x07, # white
}
def output_colorized(self, message):
# 如果是Windows系统解析ANSI转义序列并设置控制台颜色
parts = self.ansi_esc.split(message)
h = None
fd = getattr(self.stream, 'fileno', None)
#文件描述符有效并且是标准输出或标准错误获取对应的Windows句柄
if fd is not None:
fd = fd()
if fd in (1, 2): # stdout or stderr
h = ctypes.windll.kernel32.GetStdHandle(-10 - fd)
#循环处理分割后的消息部分
while parts:
text = parts.pop(0)
#如果部分是文本,写入并刷新流
if text:
self.stream.write(text)
self.stream.flush()
#如果还有部分,取出下一个部分作为参数
if parts:
params = parts.pop(0)
#如果句柄有效,将参数分割并转换为整数,初始化颜色代码
if h is not None:
params = [int(p) for p in params.split(';')]
color = 0
for p in params:
if 40 <= p <= 47:
color |= self.nt_color_map[p - 40] << 4
elif 30 <= p <= 37:
color |= self.nt_color_map[p - 30]
elif p == 1:
color |= 0x08 # foreground intensity on
elif p == 0: # reset to default color
color = 0x07
else:
pass # error condition ignored
ctypes.windll.kernel32.SetConsoleTextAttribute(h, color)
def _reset(self, message):
#重置消息的颜色
if not message.endswith(self.reset):
# 如果消息不以重置序列结尾,则添加重置序列
reset = self.reset
elif self.bold in message:
# 如果消息包含加粗,则在重置后加粗
reset = self.reset + self.bold
else:
reset = self.reset
return reset
def colorize(self, message, levelno):
# 根据日志级别给消息上色
if levelno in self.level_map and self.is_tty:
bg, fg, bold = self.level_map[levelno]
params = []
#如果背景色有效,添加背景色参数
if bg in self.color_map:
params.append(str(self.color_map[bg] + 40))
#如果前景色有效,添加前景色参数
if fg in self.color_map:
params.append(str(self.color_map[fg] + 30))
#如果需要加粗,添加加粗参数
if bold:
params.append('1')
#如果参数和消息都有效,检查消息是否有前缀(空格),并提取出来
if params and message:
if message.lstrip() != message:
prefix = re.search(r"\s+", message).group(0)
message = message[len(prefix):]
else:
prefix = ""
message = "%s%s" % (prefix, ''.join((self.csi, ';'.join(params),
'm', message, self.reset)))
return message
def format(self, record):
# 格式化日志记录
message = logging.StreamHandler.format(self, record)
return self.colorize(message, record.levelno)