]>
Commit | Line | Data |
---|---|---|
52ad194e | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
14228c0d | 2 | |
4c89c718 | 3 | #include <errno.h> |
14228c0d | 4 | #include <stdio.h> |
4c89c718 | 5 | #include <string.h> |
14228c0d MB |
6 | |
7 | #include "device-nodes.h" | |
8 | #include "utf8.h" | |
9 | ||
10 | int whitelisted_char_for_devnode(char c, const char *white) { | |
e3bff60a | 11 | |
14228c0d MB |
12 | if ((c >= '0' && c <= '9') || |
13 | (c >= 'A' && c <= 'Z') || | |
14 | (c >= 'a' && c <= 'z') || | |
15 | strchr("#+-.:=@_", c) != NULL || | |
16 | (white != NULL && strchr(white, c) != NULL)) | |
17 | return 1; | |
e3bff60a | 18 | |
14228c0d MB |
19 | return 0; |
20 | } | |
21 | ||
22 | int encode_devnode_name(const char *str, char *str_enc, size_t len) { | |
23 | size_t i, j; | |
24 | ||
52ad194e | 25 | if (!str || !str_enc) |
5eef597e | 26 | return -EINVAL; |
14228c0d MB |
27 | |
28 | for (i = 0, j = 0; str[i] != '\0'; i++) { | |
29 | int seqlen; | |
30 | ||
bb4f798a | 31 | seqlen = utf8_encoded_valid_unichar(str + i, (size_t) -1); |
14228c0d | 32 | if (seqlen > 1) { |
e3bff60a | 33 | |
14228c0d | 34 | if (len-j < (size_t)seqlen) |
e3bff60a MP |
35 | return -EINVAL; |
36 | ||
14228c0d MB |
37 | memcpy(&str_enc[j], &str[i], seqlen); |
38 | j += seqlen; | |
39 | i += (seqlen-1); | |
e3bff60a | 40 | |
14228c0d | 41 | } else if (str[i] == '\\' || !whitelisted_char_for_devnode(str[i], NULL)) { |
e3bff60a | 42 | |
14228c0d | 43 | if (len-j < 4) |
e3bff60a MP |
44 | return -EINVAL; |
45 | ||
14228c0d MB |
46 | sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); |
47 | j += 4; | |
e3bff60a | 48 | |
14228c0d MB |
49 | } else { |
50 | if (len-j < 1) | |
e3bff60a MP |
51 | return -EINVAL; |
52 | ||
14228c0d MB |
53 | str_enc[j] = str[i]; |
54 | j++; | |
55 | } | |
56 | } | |
e3bff60a | 57 | |
14228c0d | 58 | if (len-j < 1) |
e3bff60a MP |
59 | return -EINVAL; |
60 | ||
14228c0d MB |
61 | str_enc[j] = '\0'; |
62 | return 0; | |
14228c0d | 63 | } |