use crate::redis_tokenizer::{RedisTokenType, RedisTokenizer};
const REDIS_TRUNCATION_MARK: &str = "...";
const MAX_REDIS_NB_COMMANDS: usize = 3;
fn go_toupper(c: char) -> char {
if (0x16E80..=0x16EFF).contains(&(c as u32)) {
return c;
}
let mut upper = c.to_uppercase();
match (upper.next(), upper.next()) {
(Some(u), None) => u,
_ => c,
}
}
pub fn quantize_redis_string(query: &str) -> String {
let mut commands: Vec<String> = Vec::with_capacity(MAX_REDIS_NB_COMMANDS);
let mut truncated = false;
for raw_line in query.split('\n') {
if commands.len() >= MAX_REDIS_NB_COMMANDS {
break;
}
let line = raw_line.trim_matches(' ');
if line.is_empty() {
continue;
}
let mut tokens = line.split(' ').filter(|s| !s.is_empty());
let Some(first) = tokens.next() else { continue };
if first.ends_with(REDIS_TRUNCATION_MARK) {
truncated = true;
continue;
}
let cmd: String = first.chars().map(go_toupper).collect();
let command = match cmd.as_bytes() {
b"CLIENT" | b"CLUSTER" | b"COMMAND" | b"CONFIG" | b"DEBUG" | b"SCRIPT" => {
match tokens.next() {
Some(sub) if sub.ends_with(REDIS_TRUNCATION_MARK) => {
truncated = true;
continue;
}
Some(sub) => {
format!("{cmd} {}", sub.chars().map(go_toupper).collect::<String>())
}
None => cmd,
}
}
_ => cmd,
};
commands.push(command);
truncated = false;
}
let mut result = commands.join(" ");
if commands.len() == MAX_REDIS_NB_COMMANDS || truncated {
if !result.is_empty() {
result.push(' ');
}
result.push_str("...");
}
result
}
#[must_use]
pub fn obfuscate_redis_string(cmd: &str) -> String {
let cmd = cmd.trim();
let mut tokenizer = RedisTokenizer::new(cmd);
let s = &mut String::new();
let mut cmd: Option<&str> = None;
let mut args: Vec<&str> = Vec::new();
loop {
let res = tokenizer.scan();
match res.token_type {
RedisTokenType::RedisTokenCommand => {
if let Some(cmd) = cmd {
args = obfuscate_redis_cmd(s, cmd, args);
s.push('\n');
}
cmd = Some(res.token);
args.clear();
}
RedisTokenType::RedisTokenArgument => args.push(res.token),
}
if res.done {
obfuscate_redis_cmd(s, cmd.unwrap_or_default(), args);
break;
}
}
s.clone()
}
fn obfuscate_redis_cmd<'a>(str: &mut String, cmd: &'a str, mut args: Vec<&'a str>) -> Vec<&'a str> {
str.push_str(cmd);
if args.is_empty() {
return args;
}
str.push(' ');
let mut uppercase_cmd = [0; 32]; let uppercase_cmd = ascii_uppercase(cmd, &mut uppercase_cmd).unwrap_or(&[]);
match uppercase_cmd {
b"AUTH" | b"MIGRATE" | b"HELLO"
if !args.is_empty() => {
args.clear();
args.push("?");
}
b"ACL" | b"GEOHASH" | b"GEOPOS" | b"GEODIST" | b"LPUSH" | b"RPUSH" | b"SREM" | b"ZREM"
| b"SADD"
if args.len() > 1 => {
args[1] = "?";
args.drain(2..);
}
b"APPEND" | b"GETSET" | b"LPUSHX" | b"GEORADIUSBYMEMBER" | b"RPUSHX" | b"SET"
| b"SETNX" | b"SISMEMBER" | b"ZRANK" | b"ZREVRANK" | b"ZSCORE" => {
args = obfuscate_redis_args_n(args, 1);
}
b"HSETNX" | b"LREM" | b"LSET" | b"SETBIT" | b"SETEX" | b"PSETEX" | b"SETRANGE"
| b"ZINCRBY" | b"SMOVE" | b"RESTORE" => {
args = obfuscate_redis_args_n(args, 2);
}
b"LINSERT" => {
args = obfuscate_redis_args_n(args, 3);
}
b"GEOADD" => {
args = obfuscate_redis_args_step(args, 1, 3);
}
b"HMSET" | b"HSET" => {
args = obfuscate_redis_args_step(args, 1, 2);
}
b"MSET" | b"MSETNX" => {
args = obfuscate_redis_args_step(args, 0, 2);
}
b"CONFIG" => {
let mut uppercase_arg = [0; 8];
let uppercase_arg = ascii_uppercase(args[0], &mut uppercase_arg).unwrap_or(b"");
if uppercase_arg == b"SET" {
args = obfuscate_redis_args_n(args, 2);
}
}
b"BITFIELD" => {
let mut n = 0;
for (i, arg) in args.iter_mut().enumerate() {
let mut uppercase_arg = [0; 8];
let uppercase_arg = ascii_uppercase(arg, &mut uppercase_arg).unwrap_or(b"");
if uppercase_arg == b"SET" {
n = i;
}
if n > 0 && i - n == 3 {
*arg = "?";
break;
}
}
}
b"ZADD" => {
for i in 0..args.len() {
if i == 0 {
continue; }
let mut uppercase_arg = [0; 8];
let uppercase_arg = ascii_uppercase(args[i], &mut uppercase_arg).unwrap_or(b"");
match uppercase_arg {
b"NX" | b"XX" | b"CH" | b"INCR" => {}
_ => {
args = obfuscate_redis_args_step(args, i, 2);
break;
}
}
}
}
_ => {}
}
str.push_str(&args.join(" "));
args
}
fn obfuscate_redis_args_n(mut args: Vec<&str>, n: usize) -> Vec<&str> {
if args.len() > n {
args[n] = "?";
}
args
}
fn obfuscate_redis_args_step(mut args: Vec<&str>, start: usize, step: usize) -> Vec<&str> {
if start + step > args.len() {
return args;
}
for i in ((start + step - 1)..args.len()).step_by(step) {
args[i] = "?";
}
args
}
#[must_use]
pub fn remove_all_redis_args(redis_cmd: &str) -> String {
let mut redis_cmd_iter = redis_cmd.split_whitespace().peekable();
let mut obfuscated_cmd = String::new();
let Some(cmd) = redis_cmd_iter.next() else {
return obfuscated_cmd;
};
obfuscated_cmd.push_str(cmd);
if redis_cmd_iter.peek().is_none() {
return obfuscated_cmd;
}
obfuscated_cmd.push(' ');
let mut uppercase_cmd = [0; 32];
let uppercase_cmd = ascii_uppercase(cmd, &mut uppercase_cmd).unwrap_or(&[]);
match uppercase_cmd {
b"BITFIELD" => {
obfuscated_cmd.push('?');
for a in redis_cmd_iter {
let mut uppercase_arg = [0; 8];
let uppercase_arg = ascii_uppercase(a, &mut uppercase_arg).unwrap_or(b"");
if uppercase_arg == b"SET" || uppercase_arg == b"GET" || uppercase_arg == b"INCRBY"
{
obfuscated_cmd.push_str(format!(" {a} ?").as_str());
}
}
}
b"CONFIG" => {
let a = redis_cmd_iter.next().unwrap_or_default();
let mut uppercase_arg = [0; 16];
let uppercase_arg = ascii_uppercase(a, &mut uppercase_arg).unwrap_or(b"");
if uppercase_arg == b"GET"
|| uppercase_arg == b"SET"
|| uppercase_arg == b"RESETSTAT"
|| uppercase_arg == b"REWRITE"
{
obfuscated_cmd.push_str(format!("{a} ?").as_str());
} else {
obfuscated_cmd.push('?');
}
}
_ => {
obfuscated_cmd.push('?');
}
}
obfuscated_cmd
}
fn ascii_uppercase<'a>(s: &str, dest: &'a mut [u8]) -> Option<&'a [u8]> {
if s.len() > dest.len() {
return None;
}
for (i, c) in s.as_bytes().iter().enumerate() {
if c.is_ascii() {
dest[i] = c.to_ascii_uppercase();
}
}
Some(&dest[0..s.len()])
}
#[cfg(test)]
mod tests {
use duplicate::duplicate_item;
use super::{obfuscate_redis_string, quantize_redis_string, remove_all_redis_args};
#[duplicate_item(
[
test_name [test_quantize_redis_string_client]
input ["CLIENT"]
expected ["CLIENT"];
]
[
test_name [test_quantize_redis_string_client_list]
input ["CLIENT LIST"]
expected ["CLIENT LIST"];
]
[
test_name [test_quantize_redis_string_client_truncated]
input ["CLIENT ..."]
expected ["..."];
]
[
test_name [test_quantize_redis_string_get_lowercase]
input ["get my_key"]
expected ["GET"];
]
[
test_name [test_quantize_redis_string_set]
input ["SET le_key le_value"]
expected ["SET"];
]
[
test_name [test_quantize_redis_string_set_with_newlines]
input ["\n\n \nSET foo bar \n \n\n "]
expected ["SET"];
]
[
test_name [test_quantize_redis_string_config_set]
input ["CONFIG SET parameter value"]
expected ["CONFIG SET"];
]
[
test_name [test_quantize_redis_string_two_cmds]
input ["SET toto tata \n \n EXPIRE toto 15 "]
expected ["SET EXPIRE"];
]
[
test_name [test_quantize_redis_string_mset]
input ["MSET toto tata toto tata toto tata \n "]
expected ["MSET"];
]
[
test_name [test_quantize_redis_string_max_cmds]
input ["MULTI\nSET k1 v1\nSET k2 v2\nSET k3 v3\nSET k4 v4\nDEL to_del\nEXEC"]
expected ["MULTI SET SET ..."];
]
[
test_name [test_quantize_redis_string_truncation_first]
input ["GET..."]
expected ["..."];
]
[
test_name [test_quantize_redis_string_truncation_arg]
input ["GET k..."]
expected ["GET"];
]
[
test_name [test_quantize_redis_string_truncation_third]
input ["GET k1\nGET k2\nG..."]
expected ["GET GET ..."];
]
[
test_name [test_quantize_redis_string_truncation_after_max]
input ["GET k1\nGET k2\nDEL k3\nGET k..."]
expected ["GET GET DEL ..."];
]
[
test_name [test_quantize_redis_string_truncation_hdel]
input ["GET k1\nGET k2\nHDEL k3 a\nG..."]
expected ["GET GET HDEL ..."];
]
[
test_name [test_quantize_redis_string_truncation_mid]
input ["GET k...\nDEL k2\nMS..."]
expected ["GET DEL ..."];
]
[
test_name [test_quantize_redis_string_truncation_early]
input ["GET k...\nDE...\nMS..."]
expected ["GET ..."];
]
[
test_name [test_quantize_redis_string_truncation_then_cmd]
input ["GET k1\nDE...\nGET k2"]
expected ["GET GET"];
]
[
test_name [test_quantize_redis_string_truncation_complex]
input ["GET k1\nDE...\nGET k2\nHDEL k3 a\nGET k4\nDEL k5"]
expected ["GET GET HDEL ..."];
]
[
test_name [test_quantize_redis_string_unknown]
input ["UNKNOWN 123"]
expected ["UNKNOWN"];
]
[
test_name [fuzzing_3286489773]
input ["ꭺ"]
expected ["Ꭺ"];
]
[
test_name [fuzzing_2812552373]
input ["\t"]
expected ["\t"];
]
[
test_name [fuzzing_crlf]
input ["\r\n"]
// Split on \n specifically, not newlines, to copy agent's behaviour
expected ["\r"];
]
[
test_name [fuzzing_box_char]
input [""]
expected [""];
]
)]
#[test]
fn test_name() {
let result = quantize_redis_string(input);
assert_eq!(result, expected);
}
#[duplicate_item(
[
test_name [test_obfuscate_redis_string_1]
input ["AUTH my-secret-password"]
expected ["AUTH ?"];
]
[
test_name [test_obfuscate_redis_string_2]
input ["AUTH james my-secret-password"]
expected ["AUTH ?"];
]
[
test_name [test_obfuscate_redis_string_3]
input ["AUTH"]
expected ["AUTH"];
]
[
test_name [test_obfuscate_redis_string_migrate_basic]
input ["MIGRATE host port key destination-db timeout"]
expected ["MIGRATE ?"];
]
[
test_name [test_obfuscate_redis_string_migrate_with_flags]
input ["MIGRATE host port key destination-db timeout COPY REPLACE"]
expected ["MIGRATE ?"];
]
[
test_name [test_obfuscate_redis_string_migrate_with_keys]
input [r#"MIGRATE host port "" destination-db timeout KEYS key1 key2 key3"#]
expected ["MIGRATE ?"];
]
[
test_name [test_obfuscate_redis_string_migrate_no_args]
input ["MIGRATE"]
expected ["MIGRATE"];
]
[
test_name [test_obfuscate_redis_string_hello_version]
input ["HELLO 3"]
expected ["HELLO ?"];
]
[
test_name [test_obfuscate_redis_string_hello_auth]
input ["HELLO 3 AUTH username password"]
expected ["HELLO ?"];
]
[
test_name [test_obfuscate_redis_string_hello_auth_setname]
input ["HELLO 3 AUTH username password SETNAME clientname"]
expected ["HELLO ?"];
]
[
test_name [test_obfuscate_redis_string_hello_no_args]
input ["HELLO"]
expected ["HELLO"];
]
[
test_name [test_obfuscate_redis_string_acl_setuser]
input ["ACL SETUSER alice on >password ~* &* +@all"]
expected ["ACL SETUSER ?"];
]
[
test_name [test_obfuscate_redis_string_acl_setuser_complex]
input ["ACL SETUSER bob on >mysecretpassword ~keys:* resetchannels &channel:* +@all -@dangerous"]
expected ["ACL SETUSER ?"];
]
[
test_name [test_obfuscate_redis_string_acl_getuser]
input ["ACL GETUSER alice"]
expected ["ACL GETUSER ?"];
]
[
test_name [test_obfuscate_redis_string_acl_deluser]
input ["ACL DELUSER alice"]
expected ["ACL DELUSER ?"];
]
[
test_name [test_obfuscate_redis_string_acl_deluser_multi]
input ["ACL DELUSER alice bob charlie"]
expected ["ACL DELUSER ?"];
]
[
test_name [test_obfuscate_redis_string_acl_list]
input ["ACL LIST"]
expected ["ACL LIST"];
]
[
test_name [test_obfuscate_redis_string_acl_whoami]
input ["ACL WHOAMI"]
expected ["ACL WHOAMI"];
]
[
test_name [test_obfuscate_redis_string_acl_no_args]
input ["ACL"]
expected ["ACL"];
]
[
test_name [test_obfuscate_redis_string_4]
input ["APPEND key value"]
expected ["APPEND key ?"];
]
[
test_name [test_obfuscate_redis_string_5]
input ["GETSET key value"]
expected ["GETSET key ?"];
]
[
test_name [test_obfuscate_redis_string_6]
input ["LPUSHX key value"]
expected ["LPUSHX key ?"];
]
[
test_name [test_obfuscate_redis_string_7]
input ["GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]"]
expected ["GEORADIUSBYMEMBER key ? radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]"];
]
[
test_name [test_obfuscate_redis_string_8]
input ["RPUSHX key value"]
expected ["RPUSHX key ?"];
]
[
test_name [test_obfuscate_redis_string_9]
input ["SET key value"]
expected ["SET key ?"];
]
[
test_name [test_obfuscate_redis_string_10]
input ["SET key value [expiration EX seconds|PX milliseconds] [NX|XX]"]
expected ["SET key ? [expiration EX seconds|PX milliseconds] [NX|XX]"];
]
[
test_name [test_obfuscate_redis_string_11]
input ["SETNX key value"]
expected ["SETNX key ?"];
]
[
test_name [test_obfuscate_redis_string_12]
input ["SISMEMBER key member"]
expected ["SISMEMBER key ?"];
]
[
test_name [test_obfuscate_redis_string_13]
input ["ZRANK key member"]
expected ["ZRANK key ?"];
]
[
test_name [test_obfuscate_redis_string_14]
input ["ZREVRANK key member"]
expected ["ZREVRANK key ?"];
]
[
test_name [test_obfuscate_redis_string_15]
input ["ZSCORE key member"]
expected ["ZSCORE key ?"];
]
[
test_name [test_obfuscate_redis_string_16]
input ["BITFIELD key GET type offset SET type offset value INCRBY type"]
expected ["BITFIELD key GET type offset SET type offset ? INCRBY type"];
]
[
test_name [test_obfuscate_redis_string_17]
input ["BITFIELD key SET type offset value INCRBY type"]
expected ["BITFIELD key SET type offset ? INCRBY type"];
]
[
test_name [test_obfuscate_redis_string_18]
input ["BITFIELD key GET type offset INCRBY type"]
expected ["BITFIELD key GET type offset INCRBY type"];
]
[
test_name [test_obfuscate_redis_string_19]
input ["BITFIELD key SET type offset"]
expected ["BITFIELD key SET type offset"];
]
[
test_name [test_obfuscate_redis_string_20]
input ["CONFIG SET parameter value"]
expected ["CONFIG SET parameter ?"];
]
[
test_name [test_obfuscate_redis_string_21]
input ["CONFIG foo bar baz"]
expected ["CONFIG foo bar baz"];
]
[
test_name [test_obfuscate_redis_string_22]
input ["GEOADD key longitude latitude member longitude latitude member longitude latitude member"]
expected ["GEOADD key longitude latitude ? longitude latitude ? longitude latitude ?"];
]
[
test_name [test_obfuscate_redis_string_23]
input ["GEOADD key longitude latitude member longitude latitude member"]
expected ["GEOADD key longitude latitude ? longitude latitude ?"];
]
[
test_name [test_obfuscate_redis_string_24]
input ["GEOADD key longitude latitude member"]
expected ["GEOADD key longitude latitude ?"];
]
[
test_name [test_obfuscate_redis_string_25]
input ["GEOADD key longitude latitude"]
expected ["GEOADD key longitude latitude"];
]
[
test_name [test_obfuscate_redis_string_26]
input ["GEOADD key"]
expected ["GEOADD key"];
]
[
test_name [test_obfuscate_redis_string_27]
input ["GEOHASH key\nGEOPOS key\n GEODIST key"]
expected ["GEOHASH key\nGEOPOS key\nGEODIST key"];
]
[
test_name [test_obfuscate_redis_string_28]
input ["GEOHASH key member\nGEOPOS key member\nGEODIST key member\n"]
expected ["GEOHASH key ?\nGEOPOS key ?\nGEODIST key ?"];
]
[
test_name [test_obfuscate_redis_string_29]
input ["GEOHASH key member member member\nGEOPOS key member member \n GEODIST key member member member"]
expected ["GEOHASH key ?\nGEOPOS key ?\nGEODIST key ?"];
]
[
test_name [test_obfuscate_redis_string_30]
input ["GEOPOS key member [member ...]"]
expected ["GEOPOS key ?"];
]
[
test_name [test_obfuscate_redis_string_31]
input ["SREM key member [member ...]"]
expected ["SREM key ?"];
]
[
test_name [test_obfuscate_redis_string_32]
input ["ZREM key member [member ...]"]
expected ["ZREM key ?"];
]
[
test_name [test_obfuscate_redis_string_33]
input ["SADD key member [member ...]"]
expected ["SADD key ?"];
]
[
test_name [test_obfuscate_redis_string_34]
input ["GEODIST key member1 member2 [unit]"]
expected ["GEODIST key ?"];
]
[
test_name [test_obfuscate_redis_string_35]
input ["LPUSH key value [value ...]"]
expected ["LPUSH key ?"];
]
[
test_name [test_obfuscate_redis_string_36]
input ["RPUSH key value [value ...]"]
expected ["RPUSH key ?"];
]
[
test_name [test_obfuscate_redis_string_37]
input ["HSET key field value \nHSETNX key field value\nBLAH"]
expected ["HSET key field ?\nHSETNX key field ?\nBLAH"];
]
[
test_name [test_obfuscate_redis_string_38]
input ["HSET key field value"]
expected ["HSET key field ?"];
]
[
test_name [test_obfuscate_redis_string_39]
input ["HSETNX key field value"]
expected ["HSETNX key field ?"];
]
[
test_name [test_obfuscate_redis_string_40]
input ["LREM key count value"]
expected ["LREM key count ?"];
]
[
test_name [test_obfuscate_redis_string_41]
input ["LSET key index value"]
expected ["LSET key index ?"];
]
[
test_name [test_obfuscate_redis_string_42]
input ["SETBIT key offset value"]
expected ["SETBIT key offset ?"];
]
[
test_name [test_obfuscate_redis_string_43]
input ["SETRANGE key offset value"]
expected ["SETRANGE key offset ?"];
]
[
test_name [test_obfuscate_redis_string_44]
input ["SETEX key seconds value"]
expected ["SETEX key seconds ?"];
]
[
test_name [test_obfuscate_redis_string_45]
input ["PSETEX key milliseconds value"]
expected ["PSETEX key milliseconds ?"];
]
[
test_name [test_obfuscate_redis_string_46]
input ["ZINCRBY key increment member"]
expected ["ZINCRBY key increment ?"];
]
[
test_name [test_obfuscate_redis_string_47]
input ["SMOVE source destination member"]
expected ["SMOVE source destination ?"];
]
[
test_name [test_obfuscate_redis_string_48]
input ["RESTORE key ttl serialized-value [REPLACE]"]
expected ["RESTORE key ttl ? [REPLACE]"];
]
[
test_name [test_obfuscate_redis_string_49]
input ["LINSERT key BEFORE pivot value"]
expected ["LINSERT key BEFORE pivot ?"];
]
[
test_name [test_obfuscate_redis_string_50]
input ["LINSERT key AFTER pivot value"]
expected ["LINSERT key AFTER pivot ?"];
]
[
test_name [test_obfuscate_redis_string_51]
input ["HMSET key field value field value"]
expected ["HMSET key field ? field ?"];
]
[
test_name [test_obfuscate_redis_string_52]
input ["HMSET key field value \n HMSET key field value\n\n "]
expected ["HMSET key field ?\nHMSET key field ?"];
]
[
test_name [test_obfuscate_redis_string_53]
input ["HMSET key field"]
expected ["HMSET key field"];
]
[
test_name [test_obfuscate_redis_string_54]
input ["MSET key value key value"]
expected ["MSET key ? key ?"];
]
[
test_name [test_obfuscate_redis_string_55]
input ["HMSET key field"]
expected ["HMSET key field"];
]
[
test_name [test_obfuscate_redis_string_56]
input ["MSET\nMSET key value"]
expected ["MSET\nMSET key ?"];
]
[
test_name [test_obfuscate_redis_string_57]
input ["MSET key value"]
expected ["MSET key ?"];
]
[
test_name [test_obfuscate_redis_string_58]
input ["MSETNX key value key value"]
expected ["MSETNX key ? key ?"];
]
[
test_name [test_obfuscate_redis_string_59]
input ["ZADD key score member score member"]
expected ["ZADD key score ? score ?"];
]
[
test_name [test_obfuscate_redis_string_60]
input ["ZADD key NX score member score member"]
expected ["ZADD key NX score ? score ?"];
]
[
test_name [test_obfuscate_redis_string_61]
input ["ZADD key NX CH score member score member"]
expected ["ZADD key NX CH score ? score ?"];
]
[
test_name [test_obfuscate_redis_string_62]
input ["ZADD key NX CH INCR score member score member"]
expected ["ZADD key NX CH INCR score ? score ?"];
]
[
test_name [test_obfuscate_redis_string_63]
input ["ZADD key XX INCR score member score member"]
expected ["ZADD key XX INCR score ? score ?"];
]
[
test_name [test_obfuscate_redis_string_64]
input ["ZADD key XX INCR score member"]
expected ["ZADD key XX INCR score ?"];
]
[
test_name [test_obfuscate_redis_string_65]
input ["ZADD key XX INCR score"]
expected ["ZADD key XX INCR score"];
]
[
test_name [test_obfuscate_redis_string_66]
input [r"
CONFIG command
SET k v
"]
expected [r"CONFIG command
SET k ?"];
]
[
test_name [test_obfuscate_redis_string_67]
input ["HSET key field value field value"]
expected ["HSET key field ? field ?"];
]
)]
#[test]
fn test_name() {
let result = obfuscate_redis_string(input);
assert_eq!(result, expected);
}
#[duplicate_item(
[
test_name [test_obfuscate_all_redis_args_1]
input [""]
expected [""];
]
[
test_name [test_obfuscate_all_redis_args_2]
input ["SET key value"]
expected ["SET ?"];
]
[
test_name [test_obfuscate_all_redis_args_3]
input ["GET k"]
expected ["GET ?"];
]
[
test_name [test_obfuscate_all_redis_args_4]
input ["FAKECMD key value hash"]
expected ["FAKECMD ?"];
]
[
test_name [test_obfuscate_all_redis_args_5]
input ["AUTH password"]
expected ["AUTH ?"];
]
[
test_name [test_obfuscate_all_redis_args_6]
input ["GET"]
expected ["GET"];
]
[
test_name [test_obfuscate_all_redis_args_7]
input ["CONFIG SET key value"]
expected ["CONFIG SET ?"];
]
[
test_name [test_obfuscate_all_redis_args_8]
input ["CONFIG GET key"]
expected ["CONFIG GET ?"];
]
[
test_name [test_obfuscate_all_redis_args_9]
input ["CONFIG key"]
expected ["CONFIG ?"];
]
[
test_name [test_obfuscate_all_redis_args_10]
input ["BITFIELD key SET key value GET key"]
expected ["BITFIELD ? SET ? GET ?"];
]
[
test_name [test_obfuscate_all_redis_args_11]
input ["BITFIELD key INCRBY value"]
expected ["BITFIELD ? INCRBY ?"];
]
[
test_name [test_obfuscate_all_redis_args_12]
input ["BITFIELD secret key"]
expected ["BITFIELD ?"];
]
[
test_name [test_obfuscate_all_redis_args_13]
input ["set key value"]
expected ["set ?"];
]
[
test_name [test_obfuscate_all_redis_args_14]
input ["Get key"]
expected ["Get ?"];
]
[
test_name [test_obfuscate_all_redis_args_15]
input ["config key"]
expected ["config ?"];
]
[
test_name [test_obfuscate_all_redis_args_16]
input ["CONFIG get key"]
expected ["CONFIG get ?"];
]
[
test_name [test_obfuscate_all_redis_args_17]
input ["bitfield key SET key value incrby 3"]
expected ["bitfield ? SET ? incrby ?"];
]
[
test_name [test_obfuscate_fuzzing_unicode]
input ["\u{00b}ჸ"]
expected ["ჸ"];
]
[
test_name [test_obfuscate_fuzzing_whitespaces]
input ["ჸ\n\tჸ"]
expected ["ჸ ?"];
]
)]
#[test]
fn test_name() {
let result = remove_all_redis_args(input);
assert_eq!(result, expected);
}
}