libdd_trace_obfuscation/
redis.rs1use crate::redis_tokenizer::{RedisTokenType, RedisTokenizer};
5
6const REDIS_TRUNCATION_MARK: &str = "...";
7const MAX_REDIS_NB_COMMANDS: usize = 3;
8
9fn go_toupper(c: char) -> char {
13 if (0x16E80..=0x16EFF).contains(&(c as u32)) {
14 return c;
15 }
16 let mut upper = c.to_uppercase();
17 match (upper.next(), upper.next()) {
18 (Some(u), None) => u,
19 _ => c,
20 }
21}
22
23pub fn quantize_redis_string(query: &str) -> String {
25 let mut commands: Vec<String> = Vec::with_capacity(MAX_REDIS_NB_COMMANDS);
26 let mut truncated = false;
27
28 for raw_line in query.split('\n') {
30 if commands.len() >= MAX_REDIS_NB_COMMANDS {
31 break;
32 }
33
34 let line = raw_line.trim_matches(' ');
37 if line.is_empty() {
38 continue;
39 }
40
41 let mut tokens = line.split(' ').filter(|s| !s.is_empty());
44 let Some(first) = tokens.next() else { continue };
45
46 if first.ends_with(REDIS_TRUNCATION_MARK) {
47 truncated = true;
48 continue;
49 }
50
51 let cmd: String = first.chars().map(go_toupper).collect();
52 let command = match cmd.as_bytes() {
53 b"CLIENT" | b"CLUSTER" | b"COMMAND" | b"CONFIG" | b"DEBUG" | b"SCRIPT" => {
54 match tokens.next() {
55 Some(sub) if sub.ends_with(REDIS_TRUNCATION_MARK) => {
56 truncated = true;
57 continue;
58 }
59 Some(sub) => {
60 format!("{cmd} {}", sub.chars().map(go_toupper).collect::<String>())
61 }
62 None => cmd,
63 }
64 }
65 _ => cmd,
66 };
67
68 commands.push(command);
69 truncated = false;
70 }
71
72 let mut result = commands.join(" ");
73 if commands.len() == MAX_REDIS_NB_COMMANDS || truncated {
74 if !result.is_empty() {
75 result.push(' ');
76 }
77 result.push_str("...");
78 }
79 result
80}
81
82#[must_use]
83pub fn obfuscate_redis_string(cmd: &str) -> String {
84 let cmd = cmd.trim();
86 let mut tokenizer = RedisTokenizer::new(cmd);
87 let s = &mut String::new();
88 let mut cmd: Option<&str> = None;
89 let mut args: Vec<&str> = Vec::new();
90
91 loop {
92 let res = tokenizer.scan();
93 match res.token_type {
94 RedisTokenType::RedisTokenCommand => {
95 if let Some(cmd) = cmd {
96 args = obfuscate_redis_cmd(s, cmd, args);
97 s.push('\n');
98 }
99 cmd = Some(res.token);
100 args.clear();
101 }
102 RedisTokenType::RedisTokenArgument => args.push(res.token),
103 }
104 if res.done {
105 obfuscate_redis_cmd(s, cmd.unwrap_or_default(), args);
106 break;
107 }
108 }
109 s.clone()
110}
111
112fn obfuscate_redis_cmd<'a>(str: &mut String, cmd: &'a str, mut args: Vec<&'a str>) -> Vec<&'a str> {
113 str.push_str(cmd);
114 if args.is_empty() {
115 return args;
116 }
117 str.push(' ');
118 let mut uppercase_cmd = [0; 32]; let uppercase_cmd = ascii_uppercase(cmd, &mut uppercase_cmd).unwrap_or(&[]);
120 match uppercase_cmd {
121 b"AUTH" | b"MIGRATE" | b"HELLO"
122 if !args.is_empty() => {
128 args.clear();
129 args.push("?");
130 }
131 b"ACL" | b"GEOHASH" | b"GEOPOS" | b"GEODIST" | b"LPUSH" | b"RPUSH" | b"SREM" | b"ZREM"
132 | b"SADD"
133 if args.len() > 1 => {
148 args[1] = "?";
149 args.drain(2..);
150 }
151 b"APPEND" | b"GETSET" | b"LPUSHX" | b"GEORADIUSBYMEMBER" | b"RPUSHX" | b"SET"
152 | b"SETNX" | b"SISMEMBER" | b"ZRANK" | b"ZREVRANK" | b"ZSCORE" => {
153 args = obfuscate_redis_args_n(args, 1);
167 }
168 b"HSETNX" | b"LREM" | b"LSET" | b"SETBIT" | b"SETEX" | b"PSETEX" | b"SETRANGE"
169 | b"ZINCRBY" | b"SMOVE" | b"RESTORE" => {
170 args = obfuscate_redis_args_n(args, 2);
183 }
184 b"LINSERT" => {
185 args = obfuscate_redis_args_n(args, 3);
188 }
189 b"GEOADD" => {
190 args = obfuscate_redis_args_step(args, 1, 3);
193 }
194 b"HMSET" | b"HSET" => {
195 args = obfuscate_redis_args_step(args, 1, 2);
198 }
199 b"MSET" | b"MSETNX" => {
200 args = obfuscate_redis_args_step(args, 0, 2);
204 }
205 b"CONFIG" => {
206 let mut uppercase_arg = [0; 8];
209 let uppercase_arg = ascii_uppercase(args[0], &mut uppercase_arg).unwrap_or(b"");
210 if uppercase_arg == b"SET" {
211 args = obfuscate_redis_args_n(args, 2);
212 }
213 }
214 b"BITFIELD" => {
215 let mut n = 0;
219 for (i, arg) in args.iter_mut().enumerate() {
220 let mut uppercase_arg = [0; 8];
221 let uppercase_arg = ascii_uppercase(arg, &mut uppercase_arg).unwrap_or(b"");
222 if uppercase_arg == b"SET" {
223 n = i;
224 }
225 if n > 0 && i - n == 3 {
226 *arg = "?";
227 break;
228 }
229 }
230 }
231 b"ZADD" => {
232 for i in 0..args.len() {
233 if i == 0 {
234 continue; }
236 let mut uppercase_arg = [0; 8];
237 let uppercase_arg = ascii_uppercase(args[i], &mut uppercase_arg).unwrap_or(b"");
238 match uppercase_arg {
239 b"NX" | b"XX" | b"CH" | b"INCR" => {}
240 _ => {
241 args = obfuscate_redis_args_step(args, i, 2);
242 break;
243 }
244 }
245 }
246 }
247 _ => {}
248 }
249 str.push_str(&args.join(" "));
250 args
251}
252
253fn obfuscate_redis_args_n(mut args: Vec<&str>, n: usize) -> Vec<&str> {
254 if args.len() > n {
255 args[n] = "?";
256 }
257 args
258}
259
260fn obfuscate_redis_args_step(mut args: Vec<&str>, start: usize, step: usize) -> Vec<&str> {
261 if start + step > args.len() {
262 return args;
263 }
264 for i in ((start + step - 1)..args.len()).step_by(step) {
265 args[i] = "?";
266 }
267 args
268}
269
270#[must_use]
271pub fn remove_all_redis_args(redis_cmd: &str) -> String {
272 let mut redis_cmd_iter = redis_cmd.split_whitespace().peekable();
273 let mut obfuscated_cmd = String::new();
274
275 let Some(cmd) = redis_cmd_iter.next() else {
277 return obfuscated_cmd;
278 };
279 obfuscated_cmd.push_str(cmd);
280
281 if redis_cmd_iter.peek().is_none() {
284 return obfuscated_cmd;
285 }
286
287 obfuscated_cmd.push(' ');
288
289 let mut uppercase_cmd = [0; 32];
290 let uppercase_cmd = ascii_uppercase(cmd, &mut uppercase_cmd).unwrap_or(&[]);
291 match uppercase_cmd {
292 b"BITFIELD" => {
293 obfuscated_cmd.push('?');
294 for a in redis_cmd_iter {
295 let mut uppercase_arg = [0; 8];
296 let uppercase_arg = ascii_uppercase(a, &mut uppercase_arg).unwrap_or(b"");
297 if uppercase_arg == b"SET" || uppercase_arg == b"GET" || uppercase_arg == b"INCRBY"
298 {
299 obfuscated_cmd.push_str(format!(" {a} ?").as_str());
300 }
301 }
302 }
303 b"CONFIG" => {
304 let a = redis_cmd_iter.next().unwrap_or_default();
305 let mut uppercase_arg = [0; 16];
306 let uppercase_arg = ascii_uppercase(a, &mut uppercase_arg).unwrap_or(b"");
307 if uppercase_arg == b"GET"
308 || uppercase_arg == b"SET"
309 || uppercase_arg == b"RESETSTAT"
310 || uppercase_arg == b"REWRITE"
311 {
312 obfuscated_cmd.push_str(format!("{a} ?").as_str());
313 } else {
314 obfuscated_cmd.push('?');
315 }
316 }
317 _ => {
318 obfuscated_cmd.push('?');
319 }
320 }
321
322 obfuscated_cmd
323}
324
325fn ascii_uppercase<'a>(s: &str, dest: &'a mut [u8]) -> Option<&'a [u8]> {
326 if s.len() > dest.len() {
327 return None;
328 }
329 for (i, c) in s.as_bytes().iter().enumerate() {
330 if c.is_ascii() {
331 dest[i] = c.to_ascii_uppercase();
332 }
333 }
334 Some(&dest[0..s.len()])
335}
336
337#[cfg(test)]
338mod tests {
339 use duplicate::duplicate_item;
340
341 use super::{obfuscate_redis_string, quantize_redis_string, remove_all_redis_args};
342
343 #[duplicate_item(
344 [
345 test_name [test_quantize_redis_string_client]
346 input ["CLIENT"]
347 expected ["CLIENT"];
348 ]
349 [
350 test_name [test_quantize_redis_string_client_list]
351 input ["CLIENT LIST"]
352 expected ["CLIENT LIST"];
353 ]
354 [
355 test_name [test_quantize_redis_string_client_truncated]
356 input ["CLIENT ..."]
357 expected ["..."];
358 ]
359 [
360 test_name [test_quantize_redis_string_get_lowercase]
361 input ["get my_key"]
362 expected ["GET"];
363 ]
364 [
365 test_name [test_quantize_redis_string_set]
366 input ["SET le_key le_value"]
367 expected ["SET"];
368 ]
369 [
370 test_name [test_quantize_redis_string_set_with_newlines]
371 input ["\n\n \nSET foo bar \n \n\n "]
372 expected ["SET"];
373 ]
374 [
375 test_name [test_quantize_redis_string_config_set]
376 input ["CONFIG SET parameter value"]
377 expected ["CONFIG SET"];
378 ]
379 [
380 test_name [test_quantize_redis_string_two_cmds]
381 input ["SET toto tata \n \n EXPIRE toto 15 "]
382 expected ["SET EXPIRE"];
383 ]
384 [
385 test_name [test_quantize_redis_string_mset]
386 input ["MSET toto tata toto tata toto tata \n "]
387 expected ["MSET"];
388 ]
389 [
390 test_name [test_quantize_redis_string_max_cmds]
391 input ["MULTI\nSET k1 v1\nSET k2 v2\nSET k3 v3\nSET k4 v4\nDEL to_del\nEXEC"]
392 expected ["MULTI SET SET ..."];
393 ]
394 [
395 test_name [test_quantize_redis_string_truncation_first]
396 input ["GET..."]
397 expected ["..."];
398 ]
399 [
400 test_name [test_quantize_redis_string_truncation_arg]
401 input ["GET k..."]
402 expected ["GET"];
403 ]
404 [
405 test_name [test_quantize_redis_string_truncation_third]
406 input ["GET k1\nGET k2\nG..."]
407 expected ["GET GET ..."];
408 ]
409 [
410 test_name [test_quantize_redis_string_truncation_after_max]
411 input ["GET k1\nGET k2\nDEL k3\nGET k..."]
412 expected ["GET GET DEL ..."];
413 ]
414 [
415 test_name [test_quantize_redis_string_truncation_hdel]
416 input ["GET k1\nGET k2\nHDEL k3 a\nG..."]
417 expected ["GET GET HDEL ..."];
418 ]
419 [
420 test_name [test_quantize_redis_string_truncation_mid]
421 input ["GET k...\nDEL k2\nMS..."]
422 expected ["GET DEL ..."];
423 ]
424 [
425 test_name [test_quantize_redis_string_truncation_early]
426 input ["GET k...\nDE...\nMS..."]
427 expected ["GET ..."];
428 ]
429 [
430 test_name [test_quantize_redis_string_truncation_then_cmd]
431 input ["GET k1\nDE...\nGET k2"]
432 expected ["GET GET"];
433 ]
434 [
435 test_name [test_quantize_redis_string_truncation_complex]
436 input ["GET k1\nDE...\nGET k2\nHDEL k3 a\nGET k4\nDEL k5"]
437 expected ["GET GET HDEL ..."];
438 ]
439 [
440 test_name [test_quantize_redis_string_unknown]
441 input ["UNKNOWN 123"]
442 expected ["UNKNOWN"];
443 ]
444 [
445 test_name [fuzzing_3286489773]
446 input ["ꭺ"]
447 expected ["Ꭺ"];
448 ]
449 [
450 test_name [fuzzing_2812552373]
451 input ["\t"]
452 expected ["\t"];
453 ]
454 [
455 test_name [fuzzing_crlf]
456 input ["\r\n"]
457 expected ["\r"];
459 ]
460 [
461 test_name [fuzzing_box_char]
462 input [""]
463 expected [""];
464 ]
465 )]
466 #[test]
467 fn test_name() {
468 let result = quantize_redis_string(input);
469 assert_eq!(result, expected);
470 }
471
472 #[duplicate_item(
473 [
474 test_name [test_obfuscate_redis_string_1]
475 input ["AUTH my-secret-password"]
476 expected ["AUTH ?"];
477 ]
478 [
479 test_name [test_obfuscate_redis_string_2]
480 input ["AUTH james my-secret-password"]
481 expected ["AUTH ?"];
482 ]
483 [
484 test_name [test_obfuscate_redis_string_3]
485 input ["AUTH"]
486 expected ["AUTH"];
487 ]
488 [
489 test_name [test_obfuscate_redis_string_migrate_basic]
490 input ["MIGRATE host port key destination-db timeout"]
491 expected ["MIGRATE ?"];
492 ]
493 [
494 test_name [test_obfuscate_redis_string_migrate_with_flags]
495 input ["MIGRATE host port key destination-db timeout COPY REPLACE"]
496 expected ["MIGRATE ?"];
497 ]
498 [
499 test_name [test_obfuscate_redis_string_migrate_with_keys]
500 input [r#"MIGRATE host port "" destination-db timeout KEYS key1 key2 key3"#]
501 expected ["MIGRATE ?"];
502 ]
503 [
504 test_name [test_obfuscate_redis_string_migrate_no_args]
505 input ["MIGRATE"]
506 expected ["MIGRATE"];
507 ]
508 [
509 test_name [test_obfuscate_redis_string_hello_version]
510 input ["HELLO 3"]
511 expected ["HELLO ?"];
512 ]
513 [
514 test_name [test_obfuscate_redis_string_hello_auth]
515 input ["HELLO 3 AUTH username password"]
516 expected ["HELLO ?"];
517 ]
518 [
519 test_name [test_obfuscate_redis_string_hello_auth_setname]
520 input ["HELLO 3 AUTH username password SETNAME clientname"]
521 expected ["HELLO ?"];
522 ]
523 [
524 test_name [test_obfuscate_redis_string_hello_no_args]
525 input ["HELLO"]
526 expected ["HELLO"];
527 ]
528 [
529 test_name [test_obfuscate_redis_string_acl_setuser]
530 input ["ACL SETUSER alice on >password ~* &* +@all"]
531 expected ["ACL SETUSER ?"];
532 ]
533 [
534 test_name [test_obfuscate_redis_string_acl_setuser_complex]
535 input ["ACL SETUSER bob on >mysecretpassword ~keys:* resetchannels &channel:* +@all -@dangerous"]
536 expected ["ACL SETUSER ?"];
537 ]
538 [
539 test_name [test_obfuscate_redis_string_acl_getuser]
540 input ["ACL GETUSER alice"]
541 expected ["ACL GETUSER ?"];
542 ]
543 [
544 test_name [test_obfuscate_redis_string_acl_deluser]
545 input ["ACL DELUSER alice"]
546 expected ["ACL DELUSER ?"];
547 ]
548 [
549 test_name [test_obfuscate_redis_string_acl_deluser_multi]
550 input ["ACL DELUSER alice bob charlie"]
551 expected ["ACL DELUSER ?"];
552 ]
553 [
554 test_name [test_obfuscate_redis_string_acl_list]
555 input ["ACL LIST"]
556 expected ["ACL LIST"];
557 ]
558 [
559 test_name [test_obfuscate_redis_string_acl_whoami]
560 input ["ACL WHOAMI"]
561 expected ["ACL WHOAMI"];
562 ]
563 [
564 test_name [test_obfuscate_redis_string_acl_no_args]
565 input ["ACL"]
566 expected ["ACL"];
567 ]
568 [
569 test_name [test_obfuscate_redis_string_4]
570 input ["APPEND key value"]
571 expected ["APPEND key ?"];
572 ]
573 [
574 test_name [test_obfuscate_redis_string_5]
575 input ["GETSET key value"]
576 expected ["GETSET key ?"];
577 ]
578 [
579 test_name [test_obfuscate_redis_string_6]
580 input ["LPUSHX key value"]
581 expected ["LPUSHX key ?"];
582 ]
583 [
584 test_name [test_obfuscate_redis_string_7]
585 input ["GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]"]
586 expected ["GEORADIUSBYMEMBER key ? radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]"];
587 ]
588 [
589 test_name [test_obfuscate_redis_string_8]
590 input ["RPUSHX key value"]
591 expected ["RPUSHX key ?"];
592 ]
593 [
594 test_name [test_obfuscate_redis_string_9]
595 input ["SET key value"]
596 expected ["SET key ?"];
597 ]
598 [
599 test_name [test_obfuscate_redis_string_10]
600 input ["SET key value [expiration EX seconds|PX milliseconds] [NX|XX]"]
601 expected ["SET key ? [expiration EX seconds|PX milliseconds] [NX|XX]"];
602 ]
603 [
604 test_name [test_obfuscate_redis_string_11]
605 input ["SETNX key value"]
606 expected ["SETNX key ?"];
607 ]
608 [
609 test_name [test_obfuscate_redis_string_12]
610 input ["SISMEMBER key member"]
611 expected ["SISMEMBER key ?"];
612 ]
613 [
614 test_name [test_obfuscate_redis_string_13]
615 input ["ZRANK key member"]
616 expected ["ZRANK key ?"];
617 ]
618 [
619 test_name [test_obfuscate_redis_string_14]
620 input ["ZREVRANK key member"]
621 expected ["ZREVRANK key ?"];
622 ]
623 [
624 test_name [test_obfuscate_redis_string_15]
625 input ["ZSCORE key member"]
626 expected ["ZSCORE key ?"];
627 ]
628 [
629 test_name [test_obfuscate_redis_string_16]
630 input ["BITFIELD key GET type offset SET type offset value INCRBY type"]
631 expected ["BITFIELD key GET type offset SET type offset ? INCRBY type"];
632 ]
633 [
634 test_name [test_obfuscate_redis_string_17]
635 input ["BITFIELD key SET type offset value INCRBY type"]
636 expected ["BITFIELD key SET type offset ? INCRBY type"];
637 ]
638 [
639 test_name [test_obfuscate_redis_string_18]
640 input ["BITFIELD key GET type offset INCRBY type"]
641 expected ["BITFIELD key GET type offset INCRBY type"];
642 ]
643 [
644 test_name [test_obfuscate_redis_string_19]
645 input ["BITFIELD key SET type offset"]
646 expected ["BITFIELD key SET type offset"];
647 ]
648 [
649 test_name [test_obfuscate_redis_string_20]
650 input ["CONFIG SET parameter value"]
651 expected ["CONFIG SET parameter ?"];
652 ]
653 [
654 test_name [test_obfuscate_redis_string_21]
655 input ["CONFIG foo bar baz"]
656 expected ["CONFIG foo bar baz"];
657 ]
658 [
659 test_name [test_obfuscate_redis_string_22]
660 input ["GEOADD key longitude latitude member longitude latitude member longitude latitude member"]
661 expected ["GEOADD key longitude latitude ? longitude latitude ? longitude latitude ?"];
662 ]
663 [
664 test_name [test_obfuscate_redis_string_23]
665 input ["GEOADD key longitude latitude member longitude latitude member"]
666 expected ["GEOADD key longitude latitude ? longitude latitude ?"];
667 ]
668 [
669 test_name [test_obfuscate_redis_string_24]
670 input ["GEOADD key longitude latitude member"]
671 expected ["GEOADD key longitude latitude ?"];
672 ]
673 [
674 test_name [test_obfuscate_redis_string_25]
675 input ["GEOADD key longitude latitude"]
676 expected ["GEOADD key longitude latitude"];
677 ]
678 [
679 test_name [test_obfuscate_redis_string_26]
680 input ["GEOADD key"]
681 expected ["GEOADD key"];
682 ]
683 [
684 test_name [test_obfuscate_redis_string_27]
685 input ["GEOHASH key\nGEOPOS key\n GEODIST key"]
686 expected ["GEOHASH key\nGEOPOS key\nGEODIST key"];
687 ]
688 [
689 test_name [test_obfuscate_redis_string_28]
690 input ["GEOHASH key member\nGEOPOS key member\nGEODIST key member\n"]
691 expected ["GEOHASH key ?\nGEOPOS key ?\nGEODIST key ?"];
692 ]
693 [
694 test_name [test_obfuscate_redis_string_29]
695 input ["GEOHASH key member member member\nGEOPOS key member member \n GEODIST key member member member"]
696 expected ["GEOHASH key ?\nGEOPOS key ?\nGEODIST key ?"];
697 ]
698 [
699 test_name [test_obfuscate_redis_string_30]
700 input ["GEOPOS key member [member ...]"]
701 expected ["GEOPOS key ?"];
702 ]
703 [
704 test_name [test_obfuscate_redis_string_31]
705 input ["SREM key member [member ...]"]
706 expected ["SREM key ?"];
707 ]
708 [
709 test_name [test_obfuscate_redis_string_32]
710 input ["ZREM key member [member ...]"]
711 expected ["ZREM key ?"];
712 ]
713 [
714 test_name [test_obfuscate_redis_string_33]
715 input ["SADD key member [member ...]"]
716 expected ["SADD key ?"];
717 ]
718 [
719 test_name [test_obfuscate_redis_string_34]
720 input ["GEODIST key member1 member2 [unit]"]
721 expected ["GEODIST key ?"];
722 ]
723 [
724 test_name [test_obfuscate_redis_string_35]
725 input ["LPUSH key value [value ...]"]
726 expected ["LPUSH key ?"];
727 ]
728 [
729 test_name [test_obfuscate_redis_string_36]
730 input ["RPUSH key value [value ...]"]
731 expected ["RPUSH key ?"];
732 ]
733 [
734 test_name [test_obfuscate_redis_string_37]
735 input ["HSET key field value \nHSETNX key field value\nBLAH"]
736 expected ["HSET key field ?\nHSETNX key field ?\nBLAH"];
737 ]
738 [
739 test_name [test_obfuscate_redis_string_38]
740 input ["HSET key field value"]
741 expected ["HSET key field ?"];
742 ]
743 [
744 test_name [test_obfuscate_redis_string_39]
745 input ["HSETNX key field value"]
746 expected ["HSETNX key field ?"];
747 ]
748 [
749 test_name [test_obfuscate_redis_string_40]
750 input ["LREM key count value"]
751 expected ["LREM key count ?"];
752 ]
753 [
754 test_name [test_obfuscate_redis_string_41]
755 input ["LSET key index value"]
756 expected ["LSET key index ?"];
757 ]
758 [
759 test_name [test_obfuscate_redis_string_42]
760 input ["SETBIT key offset value"]
761 expected ["SETBIT key offset ?"];
762 ]
763 [
764 test_name [test_obfuscate_redis_string_43]
765 input ["SETRANGE key offset value"]
766 expected ["SETRANGE key offset ?"];
767 ]
768 [
769 test_name [test_obfuscate_redis_string_44]
770 input ["SETEX key seconds value"]
771 expected ["SETEX key seconds ?"];
772 ]
773 [
774 test_name [test_obfuscate_redis_string_45]
775 input ["PSETEX key milliseconds value"]
776 expected ["PSETEX key milliseconds ?"];
777 ]
778 [
779 test_name [test_obfuscate_redis_string_46]
780 input ["ZINCRBY key increment member"]
781 expected ["ZINCRBY key increment ?"];
782 ]
783 [
784 test_name [test_obfuscate_redis_string_47]
785 input ["SMOVE source destination member"]
786 expected ["SMOVE source destination ?"];
787 ]
788 [
789 test_name [test_obfuscate_redis_string_48]
790 input ["RESTORE key ttl serialized-value [REPLACE]"]
791 expected ["RESTORE key ttl ? [REPLACE]"];
792 ]
793 [
794 test_name [test_obfuscate_redis_string_49]
795 input ["LINSERT key BEFORE pivot value"]
796 expected ["LINSERT key BEFORE pivot ?"];
797 ]
798 [
799 test_name [test_obfuscate_redis_string_50]
800 input ["LINSERT key AFTER pivot value"]
801 expected ["LINSERT key AFTER pivot ?"];
802 ]
803 [
804 test_name [test_obfuscate_redis_string_51]
805 input ["HMSET key field value field value"]
806 expected ["HMSET key field ? field ?"];
807 ]
808 [
809 test_name [test_obfuscate_redis_string_52]
810 input ["HMSET key field value \n HMSET key field value\n\n "]
811 expected ["HMSET key field ?\nHMSET key field ?"];
812 ]
813 [
814 test_name [test_obfuscate_redis_string_53]
815 input ["HMSET key field"]
816 expected ["HMSET key field"];
817 ]
818 [
819 test_name [test_obfuscate_redis_string_54]
820 input ["MSET key value key value"]
821 expected ["MSET key ? key ?"];
822 ]
823 [
824 test_name [test_obfuscate_redis_string_55]
825 input ["HMSET key field"]
826 expected ["HMSET key field"];
827 ]
828 [
829 test_name [test_obfuscate_redis_string_56]
830 input ["MSET\nMSET key value"]
831 expected ["MSET\nMSET key ?"];
832 ]
833 [
834 test_name [test_obfuscate_redis_string_57]
835 input ["MSET key value"]
836 expected ["MSET key ?"];
837 ]
838 [
839 test_name [test_obfuscate_redis_string_58]
840 input ["MSETNX key value key value"]
841 expected ["MSETNX key ? key ?"];
842 ]
843 [
844 test_name [test_obfuscate_redis_string_59]
845 input ["ZADD key score member score member"]
846 expected ["ZADD key score ? score ?"];
847 ]
848 [
849 test_name [test_obfuscate_redis_string_60]
850 input ["ZADD key NX score member score member"]
851 expected ["ZADD key NX score ? score ?"];
852 ]
853 [
854 test_name [test_obfuscate_redis_string_61]
855 input ["ZADD key NX CH score member score member"]
856 expected ["ZADD key NX CH score ? score ?"];
857 ]
858 [
859 test_name [test_obfuscate_redis_string_62]
860 input ["ZADD key NX CH INCR score member score member"]
861 expected ["ZADD key NX CH INCR score ? score ?"];
862 ]
863 [
864 test_name [test_obfuscate_redis_string_63]
865 input ["ZADD key XX INCR score member score member"]
866 expected ["ZADD key XX INCR score ? score ?"];
867 ]
868 [
869 test_name [test_obfuscate_redis_string_64]
870 input ["ZADD key XX INCR score member"]
871 expected ["ZADD key XX INCR score ?"];
872 ]
873 [
874 test_name [test_obfuscate_redis_string_65]
875 input ["ZADD key XX INCR score"]
876 expected ["ZADD key XX INCR score"];
877 ]
878 [
879 test_name [test_obfuscate_redis_string_66]
880 input [r"
881CONFIG command
882SET k v
883 "]
884 expected [r"CONFIG command
885SET k ?"];
886 ]
887 [
888 test_name [test_obfuscate_redis_string_67]
889 input ["HSET key field value field value"]
890 expected ["HSET key field ? field ?"];
891 ]
892 )]
893 #[test]
894 fn test_name() {
895 let result = obfuscate_redis_string(input);
896 assert_eq!(result, expected);
897 }
898
899 #[duplicate_item(
900 [
901 test_name [test_obfuscate_all_redis_args_1]
902 input [""]
903 expected [""];
904 ]
905 [
906 test_name [test_obfuscate_all_redis_args_2]
907 input ["SET key value"]
908 expected ["SET ?"];
909 ]
910 [
911 test_name [test_obfuscate_all_redis_args_3]
912 input ["GET k"]
913 expected ["GET ?"];
914 ]
915 [
916 test_name [test_obfuscate_all_redis_args_4]
917 input ["FAKECMD key value hash"]
918 expected ["FAKECMD ?"];
919 ]
920 [
921 test_name [test_obfuscate_all_redis_args_5]
922 input ["AUTH password"]
923 expected ["AUTH ?"];
924 ]
925 [
926 test_name [test_obfuscate_all_redis_args_6]
927 input ["GET"]
928 expected ["GET"];
929 ]
930 [
931 test_name [test_obfuscate_all_redis_args_7]
932 input ["CONFIG SET key value"]
933 expected ["CONFIG SET ?"];
934 ]
935 [
936 test_name [test_obfuscate_all_redis_args_8]
937 input ["CONFIG GET key"]
938 expected ["CONFIG GET ?"];
939 ]
940 [
941 test_name [test_obfuscate_all_redis_args_9]
942 input ["CONFIG key"]
943 expected ["CONFIG ?"];
944 ]
945 [
946 test_name [test_obfuscate_all_redis_args_10]
947 input ["BITFIELD key SET key value GET key"]
948 expected ["BITFIELD ? SET ? GET ?"];
949 ]
950 [
951 test_name [test_obfuscate_all_redis_args_11]
952 input ["BITFIELD key INCRBY value"]
953 expected ["BITFIELD ? INCRBY ?"];
954 ]
955 [
956 test_name [test_obfuscate_all_redis_args_12]
957 input ["BITFIELD secret key"]
958 expected ["BITFIELD ?"];
959 ]
960 [
961 test_name [test_obfuscate_all_redis_args_13]
962 input ["set key value"]
963 expected ["set ?"];
964 ]
965 [
966 test_name [test_obfuscate_all_redis_args_14]
967 input ["Get key"]
968 expected ["Get ?"];
969 ]
970 [
971 test_name [test_obfuscate_all_redis_args_15]
972 input ["config key"]
973 expected ["config ?"];
974 ]
975 [
976 test_name [test_obfuscate_all_redis_args_16]
977 input ["CONFIG get key"]
978 expected ["CONFIG get ?"];
979 ]
980 [
981 test_name [test_obfuscate_all_redis_args_17]
982 input ["bitfield key SET key value incrby 3"]
983 expected ["bitfield ? SET ? incrby ?"];
984 ]
985 [
986 test_name [test_obfuscate_fuzzing_unicode]
987 input ["\u{00b}ჸ"]
988 expected ["ჸ"];
989 ]
990 [
991 test_name [test_obfuscate_fuzzing_whitespaces]
992 input ["ჸ\n\tჸ"]
993 expected ["ჸ ?"];
994 ]
995 )]
996 #[test]
997 fn test_name() {
998 let result = remove_all_redis_args(input);
999 assert_eq!(result, expected);
1000 }
1001}