]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
8f6ce71f | 2 | |
11c3a366 | 3 | #include <errno.h> |
8f6ce71f | 4 | #include <stdio.h> |
11c3a366 | 5 | #include <string.h> |
8f6ce71f DR |
6 | |
7 | #include "device-nodes.h" | |
8 | #include "utf8.h" | |
9 | ||
10 | int whitelisted_char_for_devnode(char c, const char *white) { | |
f0bc5047 | 11 | |
8f6ce71f DR |
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; | |
f0bc5047 | 18 | |
8f6ce71f DR |
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 | ||
234519ae | 25 | if (!str || !str_enc) |
7e8185ef | 26 | return -EINVAL; |
8f6ce71f DR |
27 | |
28 | for (i = 0, j = 0; str[i] != '\0'; i++) { | |
29 | int seqlen; | |
30 | ||
31 | seqlen = utf8_encoded_valid_unichar(&str[i]); | |
32 | if (seqlen > 1) { | |
f0bc5047 | 33 | |
8f6ce71f | 34 | if (len-j < (size_t)seqlen) |
f0bc5047 LP |
35 | return -EINVAL; |
36 | ||
8f6ce71f DR |
37 | memcpy(&str_enc[j], &str[i], seqlen); |
38 | j += seqlen; | |
39 | i += (seqlen-1); | |
f0bc5047 | 40 | |
8f6ce71f | 41 | } else if (str[i] == '\\' || !whitelisted_char_for_devnode(str[i], NULL)) { |
f0bc5047 | 42 | |
8f6ce71f | 43 | if (len-j < 4) |
f0bc5047 LP |
44 | return -EINVAL; |
45 | ||
8f6ce71f DR |
46 | sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); |
47 | j += 4; | |
f0bc5047 | 48 | |
8f6ce71f DR |
49 | } else { |
50 | if (len-j < 1) | |
f0bc5047 LP |
51 | return -EINVAL; |
52 | ||
8f6ce71f DR |
53 | str_enc[j] = str[i]; |
54 | j++; | |
55 | } | |
56 | } | |
f0bc5047 | 57 | |
8f6ce71f | 58 | if (len-j < 1) |
f0bc5047 LP |
59 | return -EINVAL; |
60 | ||
8f6ce71f DR |
61 | str_enc[j] = '\0'; |
62 | return 0; | |
8f6ce71f | 63 | } |