Coverage Report

Created: 2025-12-14 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tinysparql/subprojects/glib-2.80.3/glib/guuid.c
Line
Count
Source
1
/* guuid.c - UUID functions
2
 *
3
 * Copyright (C) 2013-2015, 2017 Red Hat, Inc.
4
 *
5
 * This library is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU Lesser General Public License as
7
 * published by the Free Software Foundation; either version 2.1 of the
8
 * licence, or (at your option) any later version.
9
 *
10
 * This is distributed in the hope that it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
13
 * License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
18
 * USA.
19
 *
20
 * Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
21
 */
22
23
#include "config.h"
24
#include <string.h>
25
26
#include "gi18n.h"
27
#include "gstrfuncs.h"
28
#include "grand.h"
29
#include "gmessages.h"
30
#include "gchecksum.h"
31
32
#include "guuid.h"
33
34
typedef struct {
35
  guint8 bytes[16];
36
} GUuid;
37
38
/*
39
 * g_uuid_to_string:
40
 * @uuid: a #GUuid
41
 *
42
 * Creates a string representation of @uuid, of the form
43
 * 06e023d5-86d8-420e-8103-383e4566087a (no braces nor urn:uuid:
44
 * prefix).
45
 *
46
 * Returns: (transfer full): A string that should be freed with g_free().
47
 * Since: STATIC
48
 */
49
static gchar *
50
g_uuid_to_string (const GUuid *uuid)
51
1
{
52
1
  const guint8 *bytes;
53
54
1
  g_return_val_if_fail (uuid != NULL, NULL);
55
56
1
  bytes = uuid->bytes;
57
58
1
  return g_strdup_printf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x"
59
1
                          "-%02x%02x%02x%02x%02x%02x",
60
1
                          bytes[0], bytes[1], bytes[2], bytes[3],
61
1
                          bytes[4], bytes[5], bytes[6], bytes[7],
62
1
                          bytes[8], bytes[9], bytes[10], bytes[11],
63
1
                          bytes[12], bytes[13], bytes[14], bytes[15]);
64
1
}
65
66
static gboolean
67
uuid_parse_string (const gchar *str,
68
                   GUuid       *uuid)
69
0
{
70
0
  GUuid tmp;
71
0
  guint8 *bytes = tmp.bytes;
72
0
  gint i, j, hi, lo;
73
0
  guint expected_len = 36;
74
75
0
  if (strlen (str) != expected_len)
76
0
    return FALSE;
77
78
0
  for (i = 0, j = 0; i < 16;)
79
0
    {
80
0
      if (j == 8 || j == 13 || j == 18 || j == 23)
81
0
        {
82
0
          if (str[j++] != '-')
83
0
            return FALSE;
84
85
0
          continue;
86
0
        }
87
88
0
      hi = g_ascii_xdigit_value (str[j++]);
89
0
      lo = g_ascii_xdigit_value (str[j++]);
90
91
0
      if (hi == -1 || lo == -1)
92
0
        return FALSE;
93
94
0
      bytes[i++] = hi << 4 | lo;
95
0
    }
96
97
0
  if (uuid != NULL)
98
0
    *uuid = tmp;
99
100
0
  return TRUE;
101
0
}
102
103
/**
104
 * g_uuid_string_is_valid:
105
 * @str: a string representing a UUID
106
 *
107
 * Parses the string @str and verify if it is a UUID.
108
 *
109
 * The function accepts the following syntax:
110
 *
111
 * - simple forms (e.g. `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`)
112
 *
113
 * Note that hyphens are required within the UUID string itself,
114
 * as per the aforementioned RFC.
115
 *
116
 * Returns: %TRUE if @str is a valid UUID, %FALSE otherwise.
117
 * Since: 2.52
118
 */
119
gboolean
120
g_uuid_string_is_valid (const gchar *str)
121
0
{
122
0
  g_return_val_if_fail (str != NULL, FALSE);
123
124
0
  return uuid_parse_string (str, NULL);
125
0
}
126
127
static void
128
uuid_set_version (GUuid *uuid, guint version)
129
1
{
130
1
  guint8 *bytes = uuid->bytes;
131
132
  /*
133
   * Set the four most significant bits (bits 12 through 15) of the
134
   * time_hi_and_version field to the 4-bit version number from
135
   * Section 4.1.3.
136
   */
137
1
  bytes[6] &= 0x0f;
138
1
  bytes[6] |= version << 4;
139
  /*
140
   * Set the two most significant bits (bits 6 and 7) of the
141
   * clock_seq_hi_and_reserved to zero and one, respectively.
142
   */
143
1
  bytes[8] &= 0x3f;
144
1
  bytes[8] |= 0x80;
145
1
}
146
147
/*
148
 * g_uuid_generate_v4:
149
 * @uuid: a #GUuid
150
 *
151
 * Generates a random UUID (RFC 4122 version 4).
152
 * Since: STATIC
153
 */
154
static void
155
g_uuid_generate_v4 (GUuid *uuid)
156
1
{
157
1
  int i;
158
1
  guint8 *bytes;
159
1
  guint32 *ints;
160
161
1
  g_return_if_fail (uuid != NULL);
162
163
1
  bytes = uuid->bytes;
164
1
  ints = (guint32 *) bytes;
165
5
  for (i = 0; i < 4; i++)
166
4
    ints[i] = g_random_int ();
167
168
1
  uuid_set_version (uuid, 4);
169
1
}
170
171
/**
172
 * g_uuid_string_random:
173
 *
174
 * Generates a random UUID (RFC 4122 version 4) as a string. It has the same
175
 * randomness guarantees as #GRand, so must not be used for cryptographic
176
 * purposes such as key generation, nonces, salts or one-time pads.
177
 *
178
 * Returns: (transfer full): A string that should be freed with g_free().
179
 * Since: 2.52
180
 */
181
gchar *
182
g_uuid_string_random (void)
183
1
{
184
1
  GUuid uuid;
185
186
1
  g_uuid_generate_v4 (&uuid);
187
188
1
  return g_uuid_to_string (&uuid);
189
1
}