LCOV - code coverage report
Current view: top level - common/utils - muuid.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 12 17 70.6 %
Date: 2024-10-03 20:03:20 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /* NOTE: for this file to work correctly, the random number generator
      14             :  * must have been seeded (srand) with something like the current time */
      15             : 
      16             : #include "monetdb_config.h"
      17             : #include "muuid.h"
      18             : #include <string.h> /* strdup */
      19             : #include <unistd.h>       /* for getentropy on FreeBSD */
      20             : #if defined(HAVE_GETENTROPY) && defined(HAVE_SYS_RANDOM_H)
      21             : #include <sys/random.h>
      22             : #endif
      23             : 
      24             : #if !defined(HAVE_GETENTROPY) && defined(HAVE_RAND_S)
      25             : static inline bool
      26             : generate_uuid(char *out)
      27             : {
      28             :         union {
      29             :                 unsigned int randbuf[4];
      30             :                 unsigned char uuid[16];
      31             :         } u;
      32             :         for (int i = 0; i < 4; i++)
      33             :                 if (rand_s(&u.randbuf[i]) != 0)
      34             :                         return false;
      35             :         /* make sure this is a variant 1 UUID (RFC 4122/DCE 1.1) */
      36             :         u.uuid[8] = (u.uuid[8] & 0x3F) | 0x80;
      37             :         /* make sure this is version 4 (random UUID) */
      38             :         u.uuid[6] = (u.uuid[6] & 0x0F) | 0x40;
      39             :         snprintf(out, 37,
      40             :                          "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
      41             :                          "%02x%02x%02x%02x%02x%02x",
      42             :                          u.uuid[0], u.uuid[1], u.uuid[2], u.uuid[3],
      43             :                          u.uuid[4], u.uuid[5], u.uuid[6], u.uuid[7],
      44             :                          u.uuid[8], u.uuid[9], u.uuid[10], u.uuid[11],
      45             :                          u.uuid[12], u.uuid[13], u.uuid[14], u.uuid[15]);
      46             :         return true;
      47             : }
      48             : #endif
      49             : 
      50             : char *
      51         502 : generateUUID(void)
      52             : {
      53         502 :         char out[37];
      54             : #if defined(HAVE_GETENTROPY)
      55         502 :         unsigned char randbuf[16];
      56         502 :         if (getentropy(randbuf, 16) == 0) {
      57             :                 /* make sure this is a variant 1 UUID (RFC 4122/DCE 1.1) */
      58         502 :                 randbuf[8] = (randbuf[8] & 0x3F) | 0x80;
      59             :                 /* make sure this is version 4 (random UUID) */
      60         502 :                 randbuf[6] = (randbuf[6] & 0x0F) | 0x40;
      61         502 :                 snprintf(out, sizeof(out),
      62             :                          "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
      63             :                          "%02x%02x%02x%02x%02x%02x",
      64         502 :                          randbuf[0], randbuf[1], randbuf[2], randbuf[3],
      65         502 :                          randbuf[4], randbuf[5], randbuf[6], randbuf[7],
      66         502 :                          randbuf[8], randbuf[9], randbuf[10], randbuf[11],
      67         502 :                          randbuf[12], randbuf[13], randbuf[14], randbuf[15]);
      68             :         } else
      69             : #elif defined(HAVE_RAND_S)
      70             :         if (!generate_uuid(out))
      71             : #endif
      72             :         {
      73             :                 /* generate something like this:
      74             :                  * cefa7a9c-1dd2-41b2-8350-880020adbeef
      75             :                  * ("%08x-%04x-%04x-%04x-%012x") */
      76             : #ifdef __COVERITY__
      77             :                 /* avoid rand() when checking with coverity */
      78             :                 snprintf(out, sizeof(out),
      79             :                                  "00000000-0000-0000-0000-000000000000");
      80             : #else
      81           0 :                 snprintf(out, sizeof(out),
      82             :                          "%04x%04x-%04x-4%03x-8%03x-%04x%04x%04x",
      83           0 :                          (unsigned) rand() & 0xFFFF, (unsigned) rand() & 0xFFFF,
      84           0 :                          (unsigned) rand() & 0xFFFF, (unsigned) rand() & 0x0FFF,
      85           0 :                          (unsigned) rand() & 0x0FFF, (unsigned) rand() & 0xFFFF,
      86           0 :                          (unsigned) rand() & 0xFFFF, (unsigned) rand() & 0xFFFF);
      87             : #endif
      88             :         }
      89         502 :         return strdup(out);
      90             : }

Generated by: LCOV version 1.14