Browse Source
In the process, rename udev_encode_string which is poorly named for what it does. It deals specifically with encoding names that udev creates and has its own rules: utf8 is valid but some ascii is not (e.g. path separators), and everything else is simply escaped. Rename it to encode_devnode_name.keep-around/ba91431154ad7bac82ddf0a540ec1b40db62d782

10 changed files with 172 additions and 80 deletions
@ -0,0 +1,74 @@ |
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
|||
|
|||
/***
|
|||
This file is part of systemd. |
|||
|
|||
Copyright 2012 Lennart Poettering |
|||
|
|||
systemd is free software; you can redistribute it and/or modify it |
|||
under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation; either version 2.1 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
systemd is distributed in the hope that it will be useful, but |
|||
WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|||
***/ |
|||
|
|||
#include <stdlib.h> |
|||
#include <stdio.h> |
|||
#include <stdint.h> |
|||
#include <sys/types.h> |
|||
|
|||
#include "device-nodes.h" |
|||
#include "utf8.h" |
|||
|
|||
int whitelisted_char_for_devnode(char c, const char *white) { |
|||
if ((c >= '0' && c <= '9') || |
|||
(c >= 'A' && c <= 'Z') || |
|||
(c >= 'a' && c <= 'z') || |
|||
strchr("#+-.:=@_", c) != NULL || |
|||
(white != NULL && strchr(white, c) != NULL)) |
|||
return 1; |
|||
return 0; |
|||
} |
|||
|
|||
int encode_devnode_name(const char *str, char *str_enc, size_t len) { |
|||
size_t i, j; |
|||
|
|||
if (str == NULL || str_enc == NULL) |
|||
return -1; |
|||
|
|||
for (i = 0, j = 0; str[i] != '\0'; i++) { |
|||
int seqlen; |
|||
|
|||
seqlen = utf8_encoded_valid_unichar(&str[i]); |
|||
if (seqlen > 1) { |
|||
if (len-j < (size_t)seqlen) |
|||
goto err; |
|||
memcpy(&str_enc[j], &str[i], seqlen); |
|||
j += seqlen; |
|||
i += (seqlen-1); |
|||
} else if (str[i] == '\\' || !whitelisted_char_for_devnode(str[i], NULL)) { |
|||
if (len-j < 4) |
|||
goto err; |
|||
sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); |
|||
j += 4; |
|||
} else { |
|||
if (len-j < 1) |
|||
goto err; |
|||
str_enc[j] = str[i]; |
|||
j++; |
|||
} |
|||
} |
|||
if (len-j < 1) |
|||
goto err; |
|||
str_enc[j] = '\0'; |
|||
return 0; |
|||
err: |
|||
return -1; |
|||
} |
@ -0,0 +1,23 @@ |
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
|||
|
|||
/***
|
|||
This file is part of systemd. |
|||
|
|||
Copyright 2012 Lennart Poettering |
|||
|
|||
systemd is free software; you can redistribute it and/or modify it |
|||
under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation; either version 2.1 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
systemd is distributed in the hope that it will be useful, but |
|||
WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|||
***/ |
|||
|
|||
int encode_devnode_name(const char *str, char *str_enc, size_t len); |
|||
int whitelisted_char_for_devnode(char c, const char *additional); |
@ -0,0 +1,55 @@ |
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
|||
|
|||
/***
|
|||
This file is part of systemd. |
|||
|
|||
Copyright 2013 Dave Reisner |
|||
|
|||
systemd is free software; you can redistribute it and/or modify it |
|||
under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation; either version 2.1 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
systemd is distributed in the hope that it will be useful, but |
|||
WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|||
***/ |
|||
|
|||
#include <sys/types.h> |
|||
|
|||
#include "device-nodes.h" |
|||
#include "util.h" |
|||
|
|||
/* helpers for test_encode_devnode_name */ |
|||
static char *do_encode_string(const char *in) { |
|||
size_t out_len = strlen(in) * 4; |
|||
char *out = malloc(out_len); |
|||
|
|||
assert_se(out); |
|||
assert_se(encode_devnode_name(in, out, out_len) >= 0); |
|||
puts(out); |
|||
|
|||
return out; |
|||
} |
|||
|
|||
static bool expect_encoded_as(const char *in, const char *expected) { |
|||
_cleanup_free_ char *encoded = do_encode_string(in); |
|||
return streq(encoded, expected); |
|||
} |
|||
|
|||
static void test_encode_devnode_name(void) { |
|||
assert_se(expect_encoded_as("systemd sucks", "systemd\\x20sucks")); |
|||
assert_se(expect_encoded_as("pinkiepie", "pinkiepie")); |
|||
assert_se(expect_encoded_as("valíd\\ųtf8", "valíd\\x5cųtf8")); |
|||
assert_se(expect_encoded_as("s/ash/ng", "s\\x2fash\\x2fng")); |
|||
} |
|||
|
|||
int main(int argc, char *argv[]) { |
|||
test_encode_devnode_name(); |
|||
|
|||
return 0; |
|||
} |
Loading…
Reference in new issue