r24780: More work allowing libutil to be used by external users.
[kai/samba.git] / source4 / lib / util / data_blob.c
index ac6589aa503b91a56f832997bb6b9906ee91424b..117043f95c2fd0e50480a44c1f81ce3ab13e395c 100644 (file)
@@ -6,7 +6,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -15,8 +15,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -130,27 +129,29 @@ _PUBLIC_ void data_blob_clear_free(DATA_BLOB *d)
 /**
 check if two data blobs are equal
 **/
-_PUBLIC_ BOOL data_blob_equal(const DATA_BLOB *d1, const DATA_BLOB *d2)
+_PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2)
 {
-       if (d1->length != d2->length) {
-               return False;
+       int ret;
+       if (d1->data == NULL && d2->data != NULL) {
+               return -1;
        }
-       if (d1->data == d2->data) {
-               return True;
+       if (d1->data != NULL && d2->data == NULL) {
+               return 1;
        }
-       if (d1->data == NULL || d2->data == NULL) {
-               return False;
+       if (d1->data == d2->data) {
+               return d1->length - d2->length;
        }
-       if (memcmp(d1->data, d2->data, d1->length) == 0) {
-               return True;
+       ret = memcmp(d1->data, d2->data, MIN(d1->length, d2->length));
+       if (ret == 0) {
+               return d1->length - d2->length;
        }
-       return False;
+       return ret;
 }
 
 /**
 print the data_blob as hex string
 **/
-_PUBLIC_ char *data_blob_hex_string(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
+_PUBLIC_ char *data_blob_hex_string(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
 {
        int i;
        char *hex_string;
@@ -163,6 +164,7 @@ _PUBLIC_ char *data_blob_hex_string(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
        for (i = 0; i < blob->length; i++)
                slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
 
+       hex_string[(blob->length*2)] = '\0';
        return hex_string;
 }
 
@@ -194,25 +196,37 @@ _PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length)
 /**
   realloc a data_blob
 **/
-_PUBLIC_ NTSTATUS data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length)
+_PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length)
 {
        blob->data = talloc_realloc_size(mem_ctx, blob->data, length);
-       NT_STATUS_HAVE_NO_MEMORY(blob->data);   
+       if (blob->data == NULL)
+               return false;
        blob->length = length;
-       return NT_STATUS_OK;
+       return true;
 }
 
+
 /**
   append some data to a data blob
 **/
-_PUBLIC_ NTSTATUS data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
-                         const void *p, size_t length)
+_PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
+                                  const void *p, size_t length)
 {
-       blob->data = talloc_realloc_size(mem_ctx, blob->data,
-                                        blob->length + length);
-       NT_STATUS_HAVE_NO_MEMORY(blob->data);   
-       memcpy(blob->data + blob->length, p, length);
-       blob->length += length;
-       return NT_STATUS_OK;
+       size_t old_len = blob->length;
+       size_t new_len = old_len + length;
+       if (new_len < length || new_len < old_len) {
+               return false;
+       }
+
+       if ((const uint8_t *)p + length < (const uint8_t *)p) {
+               return false;
+       }
+       
+       if (!data_blob_realloc(mem_ctx, blob, new_len)) {
+               return false;
+       }
+
+       memcpy(blob->data + old_len, p, length);
+       return true;
 }