]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/util: add dump_data_diff*() helpers
authorStefan Metzmacher <metze@samba.org>
Wed, 3 Nov 2021 10:40:13 +0000 (11:40 +0100)
committerJule Anger <janger@samba.org>
Sun, 30 Jan 2022 09:15:13 +0000 (09:15 +0000)
That will make it easy to see the difference
between two memory buffers.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14956

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit b489b7feda19b3c0f0fe2300f2c76d416776355b)

lib/util/util.c
lib/util/util.h

index 5874e6d0741d81db249816858889a57fdab14663..06977f2322979d4d3f0a53d744cccd21ae0d717c 100644 (file)
@@ -614,6 +614,90 @@ void dump_data_file(const uint8_t *buf, int len, bool omit_zero_bytes,
        dump_data_cb(buf, len, omit_zero_bytes, fprintf_cb, f);
 }
 
+/**
+ * Write dump of compared binary data to a callback
+ */
+void dump_data_diff_cb(const uint8_t *buf1, size_t len1,
+                      const uint8_t *buf2, size_t len2,
+                      bool omit_zero_bytes,
+                      void (*cb)(const char *buf, void *private_data),
+                      void *private_data)
+{
+       size_t len = MAX(len1, len2);
+       size_t i;
+       bool skipped = false;
+
+       for (i=0; i<len; i+=16) {
+               size_t remaining_len = len - i;
+               size_t remaining_len1 = 0;
+               size_t this_len1 = 0;
+               const uint8_t *this_buf1 = NULL;
+               size_t remaining_len2 = 0;
+               size_t this_len2 = 0;
+               const uint8_t *this_buf2 = NULL;
+
+               if (i < len1) {
+                       remaining_len1 = len1 - i;
+                       this_len1 = MIN(remaining_len1, 16);
+                       this_buf1 = &buf1[i];
+               }
+               if (i < len2) {
+                       remaining_len2 = len2 - i;
+                       this_len2 = MIN(remaining_len2, 16);
+                       this_buf2 = &buf2[i];
+               }
+
+               if ((omit_zero_bytes == true) &&
+                   (i > 0) && (remaining_len > 16) &&
+                   (this_len1 == 16) && all_zero(this_buf1, 16) &&
+                   (this_len2 == 16) && all_zero(this_buf2, 16))
+               {
+                       if (!skipped) {
+                               cb("skipping zero buffer bytes\n",
+                                  private_data);
+                               skipped = true;
+                       }
+                       continue;
+               }
+
+               skipped = false;
+
+               if ((this_len1 == this_len2) &&
+                   (memcmp(this_buf1, this_buf2, this_len1) == 0))
+               {
+                       dump_data_block16(" ", i, this_buf1, this_len1,
+                                         cb, private_data);
+                       continue;
+               }
+
+               dump_data_block16("-", i, this_buf1, this_len1,
+                                 cb, private_data);
+               dump_data_block16("+", i, this_buf2, this_len2,
+                                 cb, private_data);
+       }
+}
+
+_PUBLIC_ void dump_data_diff(int dbgc_class, int level,
+                            bool omit_zero_bytes,
+                            const uint8_t *buf1, size_t len1,
+                            const uint8_t *buf2, size_t len2)
+{
+       struct debug_channel_level dcl = { dbgc_class, level };
+
+       if (!DEBUGLVLC(dbgc_class, level)) {
+               return;
+       }
+       dump_data_diff_cb(buf1, len1, buf2, len2, true, debugadd_channel_cb, &dcl);
+}
+
+_PUBLIC_ void dump_data_file_diff(FILE *f,
+                                 bool omit_zero_bytes,
+                                 const uint8_t *buf1, size_t len1,
+                                 const uint8_t *buf2, size_t len2)
+{
+       dump_data_diff_cb(buf1, len1, buf2, len2, omit_zero_bytes, fprintf_cb, f);
+}
+
 /**
  malloc that aborts with smb_panic on fail or zero size.
 **/
index a7acad5688042da7a8128361e6f20b55d0ca22c7..072f04862348c95495d1ba4c2ed9f5f059af234b 100644 (file)
@@ -51,4 +51,32 @@ _PUBLIC_ void dump_data(int level, const uint8_t *buf,int len);
  */
 _PUBLIC_ void dump_data_dbgc(int dbgc_class, int level, const uint8_t *buf, int len);
 
+/**
+ * Write dump of compared binary data to a callback
+ */
+void dump_data_diff_cb(const uint8_t *buf1, size_t len1,
+                      const uint8_t *buf2, size_t len2,
+                      bool omit_zero_bytes,
+                      void (*cb)(const char *buf, void *private_data),
+                      void *private_data);
+
+/**
+ * Write dump of compared binary data to the log file.
+ *
+ * The data is only written if the log level is at least level for
+ * debug class dbgc_class.
+ */
+_PUBLIC_ void dump_data_diff(int dbgc_class, int level,
+                            bool omit_zero_bytes,
+                            const uint8_t *buf1, size_t len1,
+                            const uint8_t *buf2, size_t len2);
+
+/**
+ * Write dump of compared binary data to the given file handle
+ */
+_PUBLIC_ void dump_data_file_diff(FILE *f,
+                                 bool omit_zero_bytes,
+                                 const uint8_t *buf1, size_t len1,
+                                 const uint8_t *buf2, size_t len2);
+
 #endif