LCOV - code coverage report
Current view: top level - lib/util - data_blob.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 79 89 88.8 %
Date: 2021-09-23 10:06:22 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Easy management of byte-length data
       4             :    Copyright (C) Andrew Tridgell 2001
       5             :    Copyright (C) Andrew Bartlett 2001
       6             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "replace.h"
      22             : #include "attr.h"
      23             : #include "data_blob.h"
      24             : 
      25             : const DATA_BLOB data_blob_null = { NULL, 0 };
      26             : 
      27             : /**
      28             :  * @file
      29             :  * @brief Manipulation of arbitrary data blobs
      30             :  **/
      31             : 
      32             : /**
      33             :  construct a data blob, must be freed with data_blob_free()
      34             :  you can pass NULL for p and get a blank data blob
      35             : **/
      36     2970454 : _PUBLIC_ DATA_BLOB data_blob_named(const void *p, size_t length, const char *name)
      37             : {
      38     2970454 :         return data_blob_talloc_named(NULL, p, length, name);
      39             : }
      40             : 
      41             : /**
      42             :  construct a data blob, using supplied TALLOC_CTX
      43             : **/
      44   374659023 : _PUBLIC_ DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name)
      45             : {
      46             :         DATA_BLOB ret;
      47             : 
      48   374659023 :         if (p == NULL && length == 0) {
      49     2793660 :                 ZERO_STRUCT(ret);
      50     2793660 :                 return ret;
      51             :         }
      52             : 
      53   371865363 :         if (p) {
      54   262303079 :                 ret.data = (uint8_t *)talloc_memdup(mem_ctx, p, length);
      55             :         } else {
      56   109562284 :                 ret.data = talloc_array(mem_ctx, uint8_t, length);
      57             :         }
      58   371865363 :         if (ret.data == NULL) {
      59           0 :                 ret.length = 0;
      60           0 :                 return ret;
      61             :         }
      62   371865363 :         talloc_set_name_const(ret.data, name);
      63   371865363 :         ret.length = length;
      64   371865363 :         return ret;
      65             : }
      66             : 
      67             : /**
      68             :  construct a zero data blob, using supplied TALLOC_CTX. 
      69             :  use this sparingly as it initialises data - better to initialise
      70             :  yourself if you want specific data in the blob
      71             : **/
      72      869257 : _PUBLIC_ DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length)
      73             : {
      74      869257 :         DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, length);
      75      869257 :         data_blob_clear(&blob);
      76      869257 :         return blob;
      77             : }
      78             : 
      79             : /**
      80             : free a data blob
      81             : **/
      82    93253365 : _PUBLIC_ void data_blob_free(DATA_BLOB *d)
      83             : {
      84    93253365 :         if (d) {
      85    93253331 :                 TALLOC_FREE(d->data);
      86    93253331 :                 d->length = 0;
      87             :         }
      88    93253365 : }
      89             : 
      90             : /**
      91             : clear a DATA_BLOB's contents
      92             : **/
      93     1518926 : _PUBLIC_ void data_blob_clear(DATA_BLOB *d)
      94             : {
      95     1518926 :         if (d->data) {
      96     1299004 :                 memset_s(d->data, d->length, 0, d->length);
      97             :         }
      98     1518926 : }
      99             : 
     100             : /**
     101             : free a data blob and clear its contents
     102             : **/
     103      417366 : _PUBLIC_ void data_blob_clear_free(DATA_BLOB *d)
     104             : {
     105      417366 :         data_blob_clear(d);
     106      417366 :         data_blob_free(d);
     107      417366 : }
     108             : 
     109             : 
     110             : /**
     111             : check if two data blobs are equal
     112             : **/
     113     6288011 : _PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2)
     114             : {
     115             :         int ret;
     116     6288011 :         if (d1->data == NULL && d2->data != NULL) {
     117           0 :                 return -1;
     118             :         }
     119     6288011 :         if (d1->data != NULL && d2->data == NULL) {
     120           0 :                 return 1;
     121             :         }
     122     6288011 :         if (d1->data == d2->data) {
     123       16323 :                 return d1->length - d2->length;
     124             :         }
     125     6271688 :         ret = memcmp(d1->data, d2->data, MIN(d1->length, d2->length));
     126     6271688 :         if (ret == 0) {
     127     4125445 :                 return d1->length - d2->length;
     128             :         }
     129     2078870 :         return ret;
     130             : }
     131             : 
     132             : /**
     133             : print the data_blob as hex string
     134             : **/
     135     6419177 : _PUBLIC_ char *data_blob_hex_string_lower(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
     136             : {
     137             :         size_t i;
     138             :         char *hex_string;
     139             : 
     140     6419177 :         hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
     141     6419177 :         if (!hex_string) {
     142           0 :                 return NULL;
     143             :         }
     144             : 
     145             :         /* this must be lowercase or w2k8 cannot join a samba domain,
     146             :            as this routine is used to encode extended DNs and windows
     147             :            only accepts lowercase hexadecimal numbers */
     148   113440933 :         for (i = 0; i < blob->length; i++)
     149   110442552 :                 slprintf(&hex_string[i*2], 3, "%02x", blob->data[i]);
     150             : 
     151     6419177 :         hex_string[(blob->length*2)] = '\0';
     152     6419177 :         return hex_string;
     153             : }
     154             : 
     155     6984638 : _PUBLIC_ char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
     156             : {
     157             :         size_t i;
     158             :         char *hex_string;
     159             : 
     160     6984638 :         hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
     161     6984638 :         if (!hex_string) {
     162           0 :                 return NULL;
     163             :         }
     164             : 
     165   133917258 :         for (i = 0; i < blob->length; i++)
     166   127497271 :                 slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
     167             : 
     168     6984638 :         hex_string[(blob->length*2)] = '\0';
     169     6984638 :         return hex_string;
     170             : }
     171             : 
     172             : /**
     173             :   useful for constructing data blobs in test suites, while
     174             :   avoiding const warnings
     175             : **/
     176    50719815 : _PUBLIC_ DATA_BLOB data_blob_string_const(const char *str)
     177             : {
     178             :         DATA_BLOB blob;
     179    50719815 :         blob.data = discard_const_p(uint8_t, str);
     180    50719815 :         blob.length = str ? strlen(str) : 0;
     181    50719815 :         return blob;
     182             : }
     183             : 
     184             : /**
     185             :   useful for constructing data blobs in test suites, while
     186             :   avoiding const warnings
     187             : **/
     188      490372 : _PUBLIC_ DATA_BLOB data_blob_string_const_null(const char *str)
     189             : {
     190             :         DATA_BLOB blob;
     191      490372 :         blob.data = discard_const_p(uint8_t, str);
     192      490372 :         blob.length = str ? strlen(str)+1 : 0;
     193      490372 :         return blob;
     194             : }
     195             : 
     196             : /**
     197             :  * Create a new data blob from const data 
     198             :  */
     199             : 
     200    84574895 : _PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length)
     201             : {
     202             :         DATA_BLOB blob;
     203    84574895 :         blob.data = discard_const_p(uint8_t, p);
     204    84574895 :         blob.length = length;
     205    84574895 :         return blob;
     206             : }
     207             : 
     208             : 
     209             : /**
     210             :   realloc a data_blob
     211             : **/
     212     3177162 : _PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length)
     213             : {
     214     3177162 :         uint8_t *tmp = talloc_realloc(mem_ctx, blob->data, uint8_t, length);
     215     3177162 :         if (tmp == NULL) {
     216           0 :                 return false;
     217             :         }
     218     3177162 :         blob->data = tmp;
     219     3177162 :         blob->length = length;
     220     3177162 :         return true;
     221             : }
     222             : 
     223             : 
     224             : /**
     225             :   append some data to a data blob
     226             : **/
     227      757907 : _PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
     228             :                                    const void *p, size_t length)
     229             : {
     230      757907 :         size_t old_len = blob->length;
     231      757907 :         size_t new_len = old_len + length;
     232      757907 :         if (new_len < length || new_len < old_len) {
     233           0 :                 return false;
     234             :         }
     235             : 
     236      757907 :         if ((const uint8_t *)p + length < (const uint8_t *)p) {
     237           0 :                 return false;
     238             :         }
     239             :         
     240      757907 :         if (!data_blob_realloc(mem_ctx, blob, new_len)) {
     241           0 :                 return false;
     242             :         }
     243             : 
     244      767343 :         memcpy(blob->data + old_len, p, length);
     245      757907 :         return true;
     246             : }
     247             : 

Generated by: LCOV version 1.13