Browse code

bcomp - normalizing buffer for little endian hex comparison and simplifying automatic hex or decimal checks

Mickey Sola authored on 2018/10/09 05:57:03
Showing 1 changed files
... ...
@@ -558,8 +558,10 @@ cl_error_t cli_bcomp_compare_check(const unsigned char* buffer, size_t buffer_le
558 558
     uint32_t i = 0;
559 559
     cl_error_t ret = 0;
560 560
     uint16_t opt = 0;
561
+    uint16_t opt_val = 0;
561 562
     int64_t value = 0;
562 563
     const unsigned char* end_buf = NULL;
564
+    unsigned char* tmp_buffer = NULL;
563 565
 
564 566
     if (!buffer || !bm) {
565 567
         bcm_dbgmsg("cli_bcomp_compare_check: a param is null\n");
... ...
@@ -587,70 +589,83 @@ cl_error_t cli_bcomp_compare_check(const unsigned char* buffer, size_t buffer_le
587 587
     offset += bm->offset;
588 588
     buffer += offset;
589 589
 
590
-    bcm_dbgmsg("cli_bcomp_compare_check: literal extracted bytes before comparison %s\n", buffer);
591
-
592
-    /* grab the first byte to handle byte length options to convert the string appropriately */
593
-    switch((opt & 0x00FF)) {
594
-        /*al*/
595
-        case CLI_BCOMP_AUTO | CLI_BCOMP_LE:
596
-            errno = 0;
597
-            value = cli_strntol((char*) buffer, byte_len, (char**) &end_buf, 0);
598
-            if ((((value == LONG_MAX) || (value == LONG_MIN)) && errno == ERANGE) || NULL == end_buf) {
599
-
600
-                bcm_dbgmsg("cli_bcomp_compare_check: little endian conversion unsuccessful\n");
601
-                return CL_CLEAN;
590
+    bcm_dbgmsg("cli_bcomp_compare_check: literal extracted bytes before comparison %.*s\n", byte_len, buffer);
591
+
592
+    /* normalize buffer for little endian vals */
593
+    opt_val = opt & 0x00F0;
594
+    if (opt_val == CLI_BCOMP_LE) {
595
+        opt_val = opt & 0x000F;
596
+        if (opt_val & CLI_BCOMP_HEX || opt_val & CLI_BCOMP_AUTO) {
597
+            tmp_buffer = cli_calloc(byte_len+1, sizeof(char));
598
+            if (NULL == tmp_buffer) {
599
+                cli_errmsg("cli_bcomp_compare_check: unable to allocate memory for temp buffer\n");
600
+                return CL_EMEM;
602 601
             }
603
-            /*hle*/
604
-            if (opt & CLI_BCOMP_EXACT) {
605
-                if (buffer+byte_len != end_buf) {
606 602
 
607
-                    bcm_dbgmsg("cli_bcomp_compare_check: couldn't extract the exact number of requested bytes\n");
608
-                    return CL_CLEAN;
603
+            if (byte_len == 1) {
604
+                tmp_buffer[0] = buffer[0];
605
+            } else {
606
+                for (i = 0; i < byte_len; i = i+2) {
607
+                    if (((int32_t) byte_len - (int32_t) i) - 2 >= 0) {
608
+                        if ( isxdigit(buffer[byte_len-i-2]) || toupper(buffer[byte_len-i-2]) == 'X' ) {
609
+                            tmp_buffer[i] = buffer[byte_len-i-2];
610
+                        } else {
611
+                            tmp_buffer[i] = '0';
612
+                        }
613
+                    }
614
+
615
+                    if ( isxdigit(buffer[byte_len-i-1]) || toupper(buffer[byte_len-i-1]) == 'X' ) {
616
+                        tmp_buffer[i+1] = buffer[byte_len-i-1];
617
+                    } else {
618
+                        tmp_buffer[i+1] = '0';
619
+                    }
609 620
                 }
610 621
             }
622
+            tmp_buffer[byte_len+1] = '\0';
623
+            bcm_dbgmsg("cli_bcomp_compare_check: normalized extracted bytes before comparison %.*s\n", byte_len, tmp_buffer);
624
+        }
625
+    }
611 626
 
612
-            value = le64_to_host(value);
613
-            break;
614
-
615
-        /*ab*/  
616
-        case CLI_BCOMP_AUTO | CLI_BCOMP_BE:
617
-            value = cli_strntol((char*) buffer, byte_len, (char**) &end_buf, 0);
618
-            if ((((value == LONG_MAX) || (value == LONG_MIN)) && errno == ERANGE) || NULL == end_buf) {
619
-
620
-                bcm_dbgmsg("cli_bcomp_compare_check: big endian conversion unsuccessful\n");
621
-                return CL_CLEAN;
627
+    opt_val = opt;
628
+    if (opt_val & CLI_BCOMP_AUTO) {
629
+        if (tmp_buffer) {
630
+            if(!strncmp((char*) tmp_buffer, "0x", 2) || !strncmp((char*) tmp_buffer, "0X", 2)) {
631
+                opt |= CLI_BCOMP_HEX;
632
+            } else {
633
+                opt |= CLI_BCOMP_DEC;
622 634
             }
623
-            /*hbe*/
624
-            if (opt & CLI_BCOMP_EXACT) {
625
-                if (buffer+byte_len != end_buf) {
626
-
627
-                    bcm_dbgmsg("cli_bcomp_compare_check: couldn't extract the exact number of requested bytes\n");
628
-                    return CL_CLEAN;
629
-                }
635
+        } else {
636
+            if(!strncmp((char*) buffer, "0x", 2) || !strncmp((char*) buffer, "0X", 2)) {
637
+                opt |= CLI_BCOMP_HEX;
638
+            } else {
639
+                opt |= CLI_BCOMP_DEC;
630 640
             }
641
+        }
642
+        opt ^= CLI_BCOMP_AUTO;
643
+    }
631 644
 
632
-            value = be64_to_host(value);
633
-            break;
634
-
645
+    /* grab the first byte to handle byte length options to convert the string appropriately */
646
+    switch(opt & 0x00FF) {
635 647
         /*hl*/
636 648
         case CLI_BCOMP_HEX | CLI_BCOMP_LE:
637 649
             errno = 0;
638
-            value = cli_strntol((char*) buffer, byte_len, (char**) &end_buf, 16);
650
+            value = cli_strntol((char*) tmp_buffer, byte_len, (char**) &end_buf, 16);
639 651
             if ((((value == LONG_MAX) || (value == LONG_MIN)) && errno == ERANGE) || NULL == end_buf) {
640 652
 
653
+                free(tmp_buffer);
641 654
                 bcm_dbgmsg("cli_bcomp_compare_check: little endian hex conversion unsuccessful\n");
642 655
                 return CL_CLEAN;
643 656
             }
644 657
             /*hle*/
645 658
             if (opt & CLI_BCOMP_EXACT) {
646
-                if (buffer+byte_len != end_buf) {
659
+                if (tmp_buffer+byte_len != end_buf) {
647 660
 
661
+                    free(tmp_buffer);
648 662
                     bcm_dbgmsg("cli_bcomp_compare_check: couldn't extract the exact number of requested bytes\n");
649 663
                     return CL_CLEAN;
650 664
                 }
651 665
             }
652 666
 
653
-            value = le64_to_host(value);
654 667
             break;
655 668
 
656 669
         /*hb*/  
... ...
@@ -670,7 +685,6 @@ cl_error_t cli_bcomp_compare_check(const unsigned char* buffer, size_t buffer_le
670 670
                 }
671 671
             }
672 672
 
673
-            value = be64_to_host(value);
674 673
             break;
675 674
 
676 675
         /*dl*/
... ...
@@ -678,6 +692,9 @@ cl_error_t cli_bcomp_compare_check(const unsigned char* buffer, size_t buffer_le
678 678
             value = cli_strntol((char*) buffer, byte_len, (char**) &end_buf, 10);
679 679
             if ((((value == LONG_MAX) || (value == LONG_MIN)) && errno == ERANGE) || NULL == end_buf) {
680 680
 
681
+                if (tmp_buffer) {
682
+                    free(tmp_buffer);
683
+                }
681 684
                 bcm_dbgmsg("cli_bcomp_compare_check: little endian decimal conversion unsuccessful\n");
682 685
                 return CL_CLEAN;
683 686
             }
... ...
@@ -685,6 +702,9 @@ cl_error_t cli_bcomp_compare_check(const unsigned char* buffer, size_t buffer_le
685 685
             if (opt & CLI_BCOMP_EXACT) {
686 686
                 if (buffer+byte_len != end_buf) {
687 687
 
688
+                    if (tmp_buffer) {
689
+                        free(tmp_buffer);
690
+                    }
688 691
                     bcm_dbgmsg("cli_bcomp_compare_check: couldn't extract the exact number of requested bytes\n");
689 692
                     return CL_CLEAN;
690 693
                 }
... ...
@@ -744,9 +764,17 @@ cl_error_t cli_bcomp_compare_check(const unsigned char* buffer, size_t buffer_le
744 744
             break;
745 745
 
746 746
         default:
747
+            bcm_dbgmsg("cli_bcomp_compare_check: options were found invalid\n");
748
+            if (tmp_buffer) {
749
+                free(tmp_buffer);
750
+            }
747 751
             return CL_ENULLARG;
748 752
     }
749 753
 
754
+    if (tmp_buffer) {
755
+        free(tmp_buffer);
756
+    }
757
+
750 758
     /* do the actual comparison */
751 759
     ret = CL_CLEAN;
752 760
     for (i = 0; i < bm->comp_count; i++) {
... ...
@@ -787,7 +815,7 @@ cl_error_t cli_bcomp_compare_check(const unsigned char* buffer, size_t buffer_le
787 787
 
788 788
             if (CL_CLEAN == ret) {
789 789
                 /* comparison was not successful */
790
-                bcm_dbgmsg("cli_bcomp_compare_check: extracted value was not %c %ld\n", bm->comps[i]->comp_symbol, bm->comps[i]->comp_value);
790
+                bcm_dbgmsg("cli_bcomp_compare_check: extracted value (%ld) was not %c %ld\n", value, bm->comps[i]->comp_symbol, bm->comps[i]->comp_value);
791 791
                 return CL_CLEAN;
792 792
             }
793 793
         }