#!/usr/bin/env python

"""
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

import re

# 从sqlmap的库中导入随机范围函数、兼容模块中的xrange函数、知识库和优先级枚举
from lib.core.common import randomRange
from lib.core.compat import xrange
from lib.core.data import kb
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces each keyword character with random case value (e.g. SELECT -> SEleCt)

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0
        * SQLite 3

    Notes:
        * Useful to bypass very weak and bespoke web application firewalls
          that has poorly written permissive regular expressions
        * This tamper script should work against all (?) databases

    >>> import random
    >>> random.seed(0)
    >>> tamper('INSERT')
    'InSeRt'
    >>> tamper('f()')
    'f()'
    >>> tamper('function()')
    'FuNcTiOn()'
    >>> tamper('SELECT id FROM `user`')
    'SeLeCt id FrOm `user`'
    """

    retVal = payload

    if payload:
        # 使用正则表达式找到payload中的所有关键字(至少两个字母或下划线的单词)
        for match in re.finditer(r"\b[A-Za-z_]{2,}\b", retVal):
            word = match.group()
            # 如果单词是SQL关键字,并且不是被引号或括号包围的,或者是一个函数名
            if (word.upper() in kb.keywords and re.search(r"(?i)[`\"'\[]%s[`\"'\]]" % word, retVal) is None) or ("%s(" % word) in payload:
                # 生成一个随机大小写混合的单词
                while True:
                    _ = ""

                    for i in xrange(len(word)):
                        # 随机选择大写或小写
                        _ += word[i].upper() if randomRange(0, 1) else word[i].lower()
                    # 确保生成的单词不是全大写或全小写,并退出循环
                    if len(_) > 1 and _ not in (_.lower(), _.upper()):
                        break
                # 将原始的单词替换为随机大小写混合的单词            
                retVal = retVal.replace(word, _)

    return retVal