Skip to content

Commit 4ba22a6

Browse files
Use throw rather than abort() for guid parse failures (#992)
* Use throw rather than abort() for guid parse failures Make `winrt::guid("...")` more useful at runtime by throwing on failure instead of aborting the program. * Remove noexcept, add tests * Revert operator== changes, revise tests Co-authored-by: Kenny Kerr <[email protected]>
1 parent 20f0962 commit 4ba22a6

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

strings/base_types.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace winrt::impl
2020
};
2121

2222
template <typename T>
23-
constexpr uint8_t hex_to_uint(T const c) noexcept
23+
constexpr uint8_t hex_to_uint(T const c)
2424
{
2525
if (c >= '0' && c <= '9')
2626
{
@@ -36,22 +36,22 @@ namespace winrt::impl
3636
}
3737
else
3838
{
39-
abort();
39+
throw std::invalid_argument("Character is not a hexadecimal digit");
4040
}
4141
}
4242

4343
template <typename T>
44-
constexpr uint8_t hex_to_uint8(T const a, T const b) noexcept
44+
constexpr uint8_t hex_to_uint8(T const a, T const b)
4545
{
4646
return (hex_to_uint(a) << 4) | hex_to_uint(b);
4747
}
4848

49-
constexpr uint16_t uint8_to_uint16(uint8_t a, uint8_t b) noexcept
49+
constexpr uint16_t uint8_to_uint16(uint8_t a, uint8_t b)
5050
{
5151
return (static_cast<uint16_t>(a) << 8) | static_cast<uint16_t>(b);
5252
}
5353

54-
constexpr uint32_t uint8_to_uint32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) noexcept
54+
constexpr uint32_t uint8_to_uint32(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
5555
{
5656
return (static_cast<uint32_t>(uint8_to_uint16(a, b)) << 16) |
5757
static_cast<uint32_t>(uint8_to_uint16(c, d));
@@ -85,11 +85,11 @@ WINRT_EXPORT namespace winrt
8585
private:
8686

8787
template <typename TStringView>
88-
static constexpr guid parse(TStringView const value) noexcept
88+
static constexpr guid parse(TStringView const value)
8989
{
9090
if (value.size() != 36 || value[8] != '-' || value[13] != '-' || value[18] != '-' || value[23] != '-')
9191
{
92-
abort();
92+
throw std::invalid_argument("value is not a valid GUID string");
9393
}
9494

9595
return
@@ -179,7 +179,7 @@ WINRT_EXPORT namespace winrt
179179
{
180180
return !(left == right);
181181
}
182-
182+
183183
inline bool operator<(guid const& left, guid const& right) noexcept
184184
{
185185
return memcmp(&left, &right, sizeof(left)) < 0;

test/test/guid.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "pch.h"
2+
3+
TEST_CASE("guid")
4+
{
5+
constexpr winrt::guid expected{ 0x00112233, 0x4455, 0x6677, { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } };
6+
7+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data1 == expected.Data1);
8+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data2 == expected.Data2);
9+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data3 == expected.Data3);
10+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[0] == expected.Data4[0]);
11+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[1] == expected.Data4[1]);
12+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[2] == expected.Data4[2]);
13+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[3] == expected.Data4[3]);
14+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[4] == expected.Data4[4]);
15+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[5] == expected.Data4[5]);
16+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[6] == expected.Data4[6]);
17+
STATIC_REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff").Data4[7] == expected.Data4[7]);
18+
19+
REQUIRE(winrt::guid("00112233-4455-6677-8899-aabbccddeeff") == expected);
20+
REQUIRE(winrt::guid({ "{00112233-4455-6677-8899-aabbccddeeff}" + 1, 36 }) == expected);
21+
22+
REQUIRE_THROWS_AS(winrt::guid(""), std::invalid_argument);
23+
REQUIRE_THROWS_AS(winrt::guid("not a guid"), std::invalid_argument);
24+
REQUIRE_THROWS_AS(winrt::guid("same length string that's not a guid"), std::invalid_argument);
25+
REQUIRE_THROWS_AS(winrt::guid("too long string that's also not a guid"), std::invalid_argument);
26+
REQUIRE_THROWS_AS(winrt::guid("00112233-4455-6677-8899-aabbccddeeff with extra"), std::invalid_argument);
27+
REQUIRE_THROWS_AS(winrt::guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"), std::invalid_argument);
28+
REQUIRE_THROWS_AS(winrt::guid("{00112233-4455-6677-8899-aabbccddeeff}"), std::invalid_argument);
29+
}

test/test/test.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@
335335
<ClCompile Include="delegates.cpp" />
336336
<ClCompile Include="disconnected.cpp" />
337337
<ClCompile Include="enum.cpp" />
338+
<ClCompile Include="guid.cpp" />
338339
<ClCompile Include="hresult_class_not_registered.cpp" />
339340
<ClCompile Include="error_info.cpp" />
340341
<ClCompile Include="event_deferral.cpp" />

0 commit comments

Comments
 (0)