1mod bitwise;
12mod comparison;
13mod equality;
14
15pub use bitwise::{
16 apply_bitwise_and, apply_bitwise_and_mask, apply_bitwise_not, apply_bitwise_not_with_width,
17 apply_bitwise_xor,
18};
19pub use comparison::{
20 apply_greater_equal, apply_greater_than, apply_less_equal, apply_less_than, compare_values,
21};
22pub use equality::{apply_equal, apply_not_equal};
23
24use crate::parser::ast::{Operator, Value};
25
26#[must_use]
54pub fn apply_any_value(_left: &Value, _right: &Value) -> bool {
55 true
56}
57
58#[must_use]
151pub fn apply_operator(operator: &Operator, left: &Value, right: &Value) -> bool {
152 match operator {
153 Operator::Equal => apply_equal(left, right),
154 Operator::NotEqual => apply_not_equal(left, right),
155 Operator::LessThan => apply_less_than(left, right),
156 Operator::GreaterThan => apply_greater_than(left, right),
157 Operator::LessEqual => apply_less_equal(left, right),
158 Operator::GreaterEqual => apply_greater_equal(left, right),
159 Operator::BitwiseAnd => apply_bitwise_and(left, right),
160 Operator::BitwiseAndMask(mask) => apply_bitwise_and_mask(*mask, left, right),
161 Operator::BitwiseXor => apply_bitwise_xor(left, right),
162 Operator::BitwiseNot => apply_bitwise_not(left, right),
163 Operator::AnyValue => apply_any_value(left, right),
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_apply_operator_equal() {
173 assert!(apply_operator(
175 &Operator::Equal,
176 &Value::Uint(42),
177 &Value::Uint(42)
178 ));
179 assert!(!apply_operator(
180 &Operator::Equal,
181 &Value::Uint(42),
182 &Value::Uint(24)
183 ));
184
185 assert!(apply_operator(
187 &Operator::Equal,
188 &Value::String("hello".to_string()),
189 &Value::String("hello".to_string())
190 ));
191 assert!(!apply_operator(
192 &Operator::Equal,
193 &Value::String("hello".to_string()),
194 &Value::String("world".to_string())
195 ));
196
197 assert!(apply_operator(
199 &Operator::Equal,
200 &Value::Uint(42),
201 &Value::Int(42)
202 ));
203 }
204
205 #[test]
206 fn test_apply_operator_not_equal() {
207 assert!(!apply_operator(
209 &Operator::NotEqual,
210 &Value::Uint(42),
211 &Value::Uint(42)
212 ));
213 assert!(apply_operator(
214 &Operator::NotEqual,
215 &Value::Uint(42),
216 &Value::Uint(24)
217 ));
218
219 assert!(!apply_operator(
221 &Operator::NotEqual,
222 &Value::String("hello".to_string()),
223 &Value::String("hello".to_string())
224 ));
225 assert!(apply_operator(
226 &Operator::NotEqual,
227 &Value::String("hello".to_string()),
228 &Value::String("world".to_string())
229 ));
230
231 assert!(!apply_operator(
233 &Operator::NotEqual,
234 &Value::Uint(42),
235 &Value::Int(42)
236 ));
237 }
238
239 #[test]
240 fn test_apply_operator_bitwise_and() {
241 assert!(apply_operator(
243 &Operator::BitwiseAnd,
244 &Value::Uint(0xFF),
245 &Value::Uint(0x0F)
246 ));
247 assert!(!apply_operator(
248 &Operator::BitwiseAnd,
249 &Value::Uint(0xF0),
250 &Value::Uint(0x0F)
251 ));
252
253 assert!(apply_operator(
255 &Operator::BitwiseAnd,
256 &Value::Int(-1),
257 &Value::Int(1)
258 ));
259 assert!(!apply_operator(
260 &Operator::BitwiseAnd,
261 &Value::Int(-2),
262 &Value::Int(1)
263 ));
264
265 assert!(apply_operator(
267 &Operator::BitwiseAnd,
268 &Value::Uint(0xFF),
269 &Value::Int(0x0F)
270 ));
271
272 assert!(!apply_operator(
274 &Operator::BitwiseAnd,
275 &Value::String("test".to_string()),
276 &Value::Uint(0x01)
277 ));
278 }
279
280 #[test]
281 fn test_apply_operator_all_operators_with_same_values() {
282 let test_cases = vec![
283 (Value::Uint(42), Value::Uint(42)),
285 (Value::Int(-100), Value::Int(-100)),
286 (
287 Value::String("test".to_string()),
288 Value::String("test".to_string()),
289 ),
290 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
291 ];
292
293 for (left, right) in test_cases {
294 assert!(
296 apply_operator(&Operator::Equal, &left, &right),
297 "Equal should be true for same values: {left:?} == {right:?}"
298 );
299
300 assert!(
302 !apply_operator(&Operator::NotEqual, &left, &right),
303 "NotEqual should be false for same values: {left:?} != {right:?}"
304 );
305
306 let bitwise_result = apply_operator(&Operator::BitwiseAnd, &left, &right);
308 match &left {
309 Value::Uint(n) => {
310 let expected = *n != 0;
312 assert_eq!(
313 bitwise_result, expected,
314 "BitwiseAnd for Uint({n}) should be {expected}"
315 );
316 }
317 Value::Int(n) => {
318 let expected = *n != 0;
320 assert_eq!(
321 bitwise_result, expected,
322 "BitwiseAnd for Int({n}) should be {expected}"
323 );
324 }
325 _ => {
326 assert!(
328 !bitwise_result,
329 "BitwiseAnd should be false for non-integer types: {left:?}"
330 );
331 }
332 }
333 }
334 }
335
336 #[test]
337 fn test_apply_operator_all_operators_with_different_values() {
338 let test_cases = vec![
339 (Value::Uint(42), Value::Uint(24)),
341 (Value::Int(100), Value::Int(-100)),
342 (
343 Value::String("hello".to_string()),
344 Value::String("world".to_string()),
345 ),
346 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![4, 5, 6])),
347 (Value::Uint(42), Value::String("42".to_string())),
349 (Value::Int(42), Value::Bytes(vec![42])),
350 ];
351
352 for (left, right) in test_cases {
353 assert!(
355 !apply_operator(&Operator::Equal, &left, &right),
356 "Equal should be false for different values: {left:?} == {right:?}"
357 );
358
359 assert!(
361 apply_operator(&Operator::NotEqual, &left, &right),
362 "NotEqual should be true for different values: {left:?} != {right:?}"
363 );
364
365 let bitwise_result = apply_operator(&Operator::BitwiseAnd, &left, &right);
367 match (&left, &right) {
368 (Value::Uint(a), Value::Uint(b)) => {
369 let expected = (a & b) != 0;
370 assert_eq!(
371 bitwise_result, expected,
372 "BitwiseAnd for Uint({a}) & Uint({b}) should be {expected}"
373 );
374 }
375 (Value::Int(a), Value::Int(b)) => {
376 #[allow(clippy::cast_sign_loss)]
377 let expected = ((*a as u64) & (*b as u64)) != 0;
378 assert_eq!(
379 bitwise_result, expected,
380 "BitwiseAnd for Int({a}) & Int({b}) should be {expected}"
381 );
382 }
383 (Value::Uint(a), Value::Int(b)) | (Value::Int(b), Value::Uint(a)) => {
384 #[allow(clippy::cast_sign_loss)]
385 let expected = (a & (*b as u64)) != 0;
386 assert_eq!(
387 bitwise_result, expected,
388 "BitwiseAnd for mixed Uint/Int should be {expected}"
389 );
390 }
391 _ => {
392 assert!(
394 !bitwise_result,
395 "BitwiseAnd should be false for non-integer types: {left:?} & {right:?}"
396 );
397 }
398 }
399 }
400 }
401
402 #[test]
403 fn test_apply_operator_consistency_with_individual_functions() {
404 let test_cases = vec![
405 (Value::Uint(42), Value::Uint(42)),
406 (Value::Uint(42), Value::Uint(24)),
407 (Value::Int(-100), Value::Int(-100)),
408 (Value::Int(100), Value::Int(-100)),
409 (
410 Value::String("test".to_string()),
411 Value::String("test".to_string()),
412 ),
413 (
414 Value::String("hello".to_string()),
415 Value::String("world".to_string()),
416 ),
417 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
418 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![4, 5, 6])),
419 (Value::Uint(42), Value::Int(42)),
421 (Value::Uint(42), Value::String("42".to_string())),
422 (Value::Int(42), Value::Bytes(vec![42])),
423 ];
424
425 for (left, right) in test_cases {
426 assert_eq!(
428 apply_operator(&Operator::Equal, &left, &right),
429 apply_equal(&left, &right),
430 "apply_operator(Equal) should match apply_equal for {left:?}, {right:?}"
431 );
432
433 assert_eq!(
434 apply_operator(&Operator::NotEqual, &left, &right),
435 apply_not_equal(&left, &right),
436 "apply_operator(NotEqual) should match apply_not_equal for {left:?}, {right:?}"
437 );
438
439 assert_eq!(
440 apply_operator(&Operator::BitwiseAnd, &left, &right),
441 apply_bitwise_and(&left, &right),
442 "apply_operator(BitwiseAnd) should match apply_bitwise_and for {left:?}, {right:?}"
443 );
444
445 assert_eq!(
446 apply_operator(&Operator::BitwiseXor, &left, &right),
447 apply_bitwise_xor(&left, &right),
448 "apply_operator(BitwiseXor) should match apply_bitwise_xor for {left:?}, {right:?}"
449 );
450
451 assert_eq!(
452 apply_operator(&Operator::BitwiseNot, &left, &right),
453 apply_bitwise_not(&left, &right),
454 "apply_operator(BitwiseNot) should match apply_bitwise_not for {left:?}, {right:?}"
455 );
456
457 assert!(
458 apply_operator(&Operator::AnyValue, &left, &right),
459 "apply_operator(AnyValue) should always be true for {left:?}, {right:?}"
460 );
461 }
462 }
463
464 #[test]
465 fn test_apply_operator_magic_rule_scenarios() {
466 let elf_magic = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
470 let elf_expected = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
471 assert!(apply_operator(&Operator::Equal, &elf_magic, &elf_expected));
472 assert!(!apply_operator(
473 &Operator::NotEqual,
474 &elf_magic,
475 &elf_expected
476 ));
477
478 let zip_magic = Value::Uint(0x504B_0304);
480 let zip_expected = Value::Uint(0x504B_0304);
481 assert!(apply_operator(&Operator::Equal, &zip_magic, &zip_expected));
482
483 let flags = Value::Uint(0b1101_0110);
485 let flag_mask = Value::Uint(0b0000_0010); assert!(apply_operator(&Operator::BitwiseAnd, &flags, &flag_mask));
487
488 let no_flag_mask = Value::Uint(0b0000_0001); assert!(!apply_operator(
490 &Operator::BitwiseAnd,
491 &flags,
492 &no_flag_mask
493 ));
494
495 let content = Value::String("#!/bin/bash".to_string());
497 let shebang = Value::String("#!/bin/bash".to_string());
498 assert!(apply_operator(&Operator::Equal, &content, &shebang));
499
500 let not_shebang = Value::String("#!/usr/bin/python".to_string());
501 assert!(apply_operator(&Operator::NotEqual, &content, ¬_shebang));
502
503 let version = Value::Uint(2);
505 let expected_version = Value::Uint(2);
506 let old_version = Value::Uint(1);
507 assert!(apply_operator(
508 &Operator::Equal,
509 &version,
510 &expected_version
511 ));
512 assert!(apply_operator(&Operator::NotEqual, &version, &old_version));
513 }
514
515 #[test]
516 fn test_apply_operator_edge_cases() {
517 let max_uint = Value::Uint(u64::MAX);
519 let min_signed = Value::Int(i64::MIN);
520 let max_signed = Value::Int(i64::MAX);
521
522 assert!(apply_operator(&Operator::Equal, &max_uint, &max_uint));
524 assert!(apply_operator(&Operator::Equal, &min_signed, &min_signed));
525 assert!(apply_operator(&Operator::Equal, &max_signed, &max_signed));
526
527 assert!(apply_operator(&Operator::NotEqual, &max_uint, &min_signed));
529 assert!(apply_operator(
530 &Operator::NotEqual,
531 &max_signed,
532 &min_signed
533 ));
534
535 assert!(apply_operator(
537 &Operator::BitwiseAnd,
538 &max_uint,
539 &Value::Uint(1)
540 ));
541 assert!(apply_operator(
542 &Operator::BitwiseAnd,
543 &min_signed,
544 &min_signed
545 ));
546
547 let empty_bytes = Value::Bytes(vec![]);
549 let empty_string = Value::String(String::new());
550 assert!(apply_operator(&Operator::Equal, &empty_bytes, &empty_bytes));
551 assert!(apply_operator(
552 &Operator::Equal,
553 &empty_string,
554 &empty_string
555 ));
556 assert!(apply_operator(
557 &Operator::NotEqual,
558 &empty_bytes,
559 &empty_string
560 ));
561
562 let zero_uint = Value::Uint(0);
564 let zero_signed = Value::Int(0);
565 assert!(!apply_operator(
566 &Operator::BitwiseAnd,
567 &zero_uint,
568 &Value::Uint(0xFF)
569 ));
570 assert!(!apply_operator(
571 &Operator::BitwiseAnd,
572 &zero_signed,
573 &Value::Int(0xFF)
574 ));
575 assert!(!apply_operator(
576 &Operator::NotEqual,
577 &zero_uint,
578 &zero_signed
579 )); }
581
582 #[test]
583 fn test_apply_operator_bitwise_xor() {
584 assert!(apply_operator(
585 &Operator::BitwiseXor,
586 &Value::Uint(0xFF),
587 &Value::Uint(0x0F)
588 ));
589 assert!(!apply_operator(
590 &Operator::BitwiseXor,
591 &Value::Uint(42),
592 &Value::Uint(42)
593 ));
594 assert!(!apply_operator(
595 &Operator::BitwiseXor,
596 &Value::String("x".to_string()),
597 &Value::Uint(1)
598 ));
599 }
600
601 #[test]
602 fn test_apply_operator_bitwise_not() {
603 assert!(apply_operator(
604 &Operator::BitwiseNot,
605 &Value::Uint(0),
606 &Value::Uint(u64::MAX)
607 ));
608 assert!(apply_operator(
609 &Operator::BitwiseNot,
610 &Value::Int(-1),
611 &Value::Int(0)
612 ));
613 assert!(!apply_operator(
614 &Operator::BitwiseNot,
615 &Value::Bytes(vec![0]),
616 &Value::Uint(0xFF)
617 ));
618 }
619
620 #[test]
621 fn test_apply_operator_any_value() {
622 assert!(apply_operator(
623 &Operator::AnyValue,
624 &Value::Uint(0),
625 &Value::Uint(0)
626 ));
627 assert!(apply_operator(
628 &Operator::AnyValue,
629 &Value::Int(42),
630 &Value::Int(0)
631 ));
632 assert!(apply_operator(
633 &Operator::AnyValue,
634 &Value::Bytes(vec![1, 2, 3]),
635 &Value::Bytes(vec![])
636 ));
637 assert!(apply_operator(
638 &Operator::AnyValue,
639 &Value::String("x".to_string()),
640 &Value::String("y".to_string())
641 ));
642 assert!(apply_operator(
643 &Operator::AnyValue,
644 &Value::Uint(1),
645 &Value::String(String::new())
646 ));
647 assert!(apply_operator(
648 &Operator::AnyValue,
649 &Value::Bytes(vec![]),
650 &Value::Bytes(vec![])
651 ));
652 }
653
654 #[test]
655 fn test_apply_operator_all_combinations() {
656 let operators = [
657 Operator::Equal,
658 Operator::NotEqual,
659 Operator::LessThan,
660 Operator::GreaterThan,
661 Operator::LessEqual,
662 Operator::GreaterEqual,
663 Operator::BitwiseAnd,
664 Operator::BitwiseAndMask(0xFF),
665 Operator::BitwiseXor,
666 Operator::BitwiseNot,
667 Operator::AnyValue,
668 ];
669 let values = [
670 Value::Uint(42),
671 Value::Int(-42),
672 Value::Bytes(vec![42]),
673 Value::String("42".to_string()),
674 ];
675
676 for operator in &operators {
678 for left in &values {
679 for right in &values {
680 let result = apply_operator(operator, left, right);
682
683 let expected = match operator {
685 Operator::Equal => apply_equal(left, right),
686 Operator::NotEqual => apply_not_equal(left, right),
687 Operator::LessThan => apply_less_than(left, right),
688 Operator::GreaterThan => apply_greater_than(left, right),
689 Operator::LessEqual => apply_less_equal(left, right),
690 Operator::GreaterEqual => apply_greater_equal(left, right),
691 Operator::BitwiseAnd => apply_bitwise_and(left, right),
692 Operator::BitwiseAndMask(mask) => {
693 apply_bitwise_and_mask(*mask, left, right)
694 }
695 Operator::BitwiseXor => apply_bitwise_xor(left, right),
696 Operator::BitwiseNot => apply_bitwise_not(left, right),
697 Operator::AnyValue => apply_any_value(left, right),
698 };
699
700 assert_eq!(
701 result, expected,
702 "apply_operator({operator:?}, {left:?}, {right:?}) should match individual function"
703 );
704 }
705 }
706 }
707 }
708}