]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
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" | |
ff25d338 | 8 | #include "string-util.h" |
8f6ce71f DR |
9 | #include "utf8.h" |
10 | ||
8352a29b | 11 | int allow_listed_char_for_devnode(char c, const char *additional) { |
c68ede39 | 12 | return |
ff25d338 LP |
13 | ascii_isdigit(c) || |
14 | ascii_isalpha(c) || | |
c68ede39 | 15 | strchr("#+-.:=@_", c) || |
8352a29b | 16 | (additional && strchr(additional, c)); |
8f6ce71f DR |
17 | } |
18 | ||
19 | int encode_devnode_name(const char *str, char *str_enc, size_t len) { | |
20 | size_t i, j; | |
21 | ||
234519ae | 22 | if (!str || !str_enc) |
7e8185ef | 23 | return -EINVAL; |
8f6ce71f DR |
24 | |
25 | for (i = 0, j = 0; str[i] != '\0'; i++) { | |
26 | int seqlen; | |
27 | ||
f5fbe71d | 28 | seqlen = utf8_encoded_valid_unichar(str + i, SIZE_MAX); |
8f6ce71f | 29 | if (seqlen > 1) { |
f0bc5047 | 30 | |
c68ede39 | 31 | if (len-j < (size_t) seqlen) |
f0bc5047 LP |
32 | return -EINVAL; |
33 | ||
8f6ce71f DR |
34 | memcpy(&str_enc[j], &str[i], seqlen); |
35 | j += seqlen; | |
36 | i += (seqlen-1); | |
f0bc5047 | 37 | |
6b000af4 | 38 | } else if (str[i] == '\\' || !allow_listed_char_for_devnode(str[i], NULL)) { |
f0bc5047 | 39 | |
8f6ce71f | 40 | if (len-j < 4) |
f0bc5047 LP |
41 | return -EINVAL; |
42 | ||
8f6ce71f DR |
43 | sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); |
44 | j += 4; | |
f0bc5047 | 45 | |
8f6ce71f DR |
46 | } else { |
47 | if (len-j < 1) | |
f0bc5047 LP |
48 | return -EINVAL; |
49 | ||
8f6ce71f DR |
50 | str_enc[j] = str[i]; |
51 | j++; | |
52 | } | |
53 | } | |
f0bc5047 | 54 | |
8f6ce71f | 55 | if (len-j < 1) |
f0bc5047 LP |
56 | return -EINVAL; |
57 | ||
8f6ce71f DR |
58 | str_enc[j] = '\0'; |
59 | return 0; | |
8f6ce71f | 60 | } |