2 * libefivar - library for the manipulation of EFI variables
3 * Copyright 2012-2013 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify 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 * License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see
17 * <http://www.gnu.org/licenses/>.
21 #ifndef LIBEFIVAR_GUID_H
22 #define LIBEFIVAR_GUID_H 1
29 #include "efivar_endian.h"
31 #define GUID_FORMAT "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x"
36 char spaces[] = " \f\n\r\t\v";
37 for (int i = 0; spaces[i] != '\0'; i++)
44 check_sanity(const char *text, size_t len)
46 size_t sl = strlen("84be9c3e-8a32-42c0-891c-4cd3b072becc");
51 else if (len > sl && !real_isspace(text[sl]))
54 if (text[8] != '-' || text[13] != '-' || text[18] != '-' ||
63 check_segment_sanity(const char *text, size_t len)
65 for(unsigned int i = 0; i < len; i++) {
66 if (text[i] >= '0' && text[i] <= '9')
68 /* "| 0x20" is tolower() without having to worry about
69 * locale concerns, since we know everything here must
70 * be within traditional ascii space. */
71 if ((text[i] | 0x20) >= 'a' && (text[i] | 0x20) <= 'f')
79 static inline int UNUSED
80 text_to_guid(const char *text, efi_guid_t *guid)
82 /* these variables represent the length of the /string/ they hold,
83 * not the interpreted length of the value from them. Mostly the
84 * names make it more obvious to verify that my bounds checking is
86 char eightbytes[9] = "";
87 char fourbytes[5] = "";
88 char twobytes[3] = "";
89 size_t textlen = strlen(text);
90 size_t guidlen = strlen("84be9c3e-8a32-42c0-891c-4cd3b072becc");
92 if (textlen == guidlen + 2) {
93 if (text[0] != '{' || text[textlen - 1] != '}') {
101 if (check_sanity(text, textlen) < 0)
104 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
106 strncpy(eightbytes, text, 8);
107 if (check_segment_sanity(eightbytes, 8) < 0)
109 guid->a = (uint32_t)strtoul(eightbytes, NULL, 16);
110 guid->a = cpu_to_le32(guid->a);
112 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
114 strncpy(fourbytes, text+9, 4);
115 if (check_segment_sanity(fourbytes, 4) < 0)
117 guid->b = (uint16_t)strtoul(fourbytes, NULL, 16);
118 guid->b = cpu_to_le16(guid->b);
120 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
122 strncpy(fourbytes, text+14, 4);
123 if (check_segment_sanity(fourbytes, 4) < 0)
125 guid->c = (uint16_t)strtoul(fourbytes, NULL, 16);
126 guid->c = cpu_to_le16(guid->c);
128 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
130 strncpy(fourbytes, text+19, 4);
131 if (check_segment_sanity(fourbytes, 4) < 0)
133 guid->d = (uint16_t)strtoul(fourbytes, NULL, 16);
134 guid->d = cpu_to_be16(guid->d);
136 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
138 strncpy(twobytes, text+24, 2);
139 if (check_segment_sanity(twobytes, 2) < 0)
141 guid->e[0] = (uint8_t)strtoul(twobytes, NULL, 16);
143 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
145 strncpy(twobytes, text+26, 2);
146 if (check_segment_sanity(twobytes, 2) < 0)
148 guid->e[1] = (uint8_t)strtoul(twobytes, NULL, 16);
150 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
152 strncpy(twobytes, text+28, 2);
153 if (check_segment_sanity(twobytes, 2) < 0)
155 guid->e[2] = (uint8_t)strtoul(twobytes, NULL, 16);
157 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
159 strncpy(twobytes, text+30, 2);
160 if (check_segment_sanity(twobytes, 2) < 0)
162 guid->e[3] = (uint8_t)strtoul(twobytes, NULL, 16);
164 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
166 strncpy(twobytes, text+32, 2);
167 if (check_segment_sanity(twobytes, 2) < 0)
169 guid->e[4] = (uint8_t)strtoul(twobytes, NULL, 16);
171 /* 84be9c3e-8a32-42c0-891c-4cd3b072becc
173 strncpy(twobytes, text+34, 2);
174 if (check_segment_sanity(twobytes, 2) < 0)
176 guid->e[5] = (uint8_t)strtoul(twobytes, NULL, 16);
187 #endif /* LIBEFIVAR_GUID */