From 518da2798925089c6605c0ff745be7976bbc0dd7 Mon Sep 17 00:00:00 2001 From: J. Ali Harlow Date: Fri, 17 Oct 2014 10:13:48 +0100 Subject: [PATCH] Add missing files --- librazor/path.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++ librazor/test-pfu.c | 134 +++++++++++++++++++++++++++++++++++ 2 files changed, 327 insertions(+), 0 deletions(-) create mode 100644 librazor/path.c create mode 100644 librazor/test-pfu.c diff --git a/librazor/path.c b/librazor/path.c new file mode 100644 index 0000000..34b4a4e --- /dev/null +++ b/librazor/path.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2014 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include +#include +#include "razor.h" +#include "razor-internal.h" + +/** + * razor_path_add_root: + * + * Adds a root to a path. path must be an absolute pathname. In POSIX + * environments this is equivalent to the concationation of root and path. + * In Microsoft Windows an adjustment may need to be made for a drive letter + * in path (which will be dropped). + * + * Returns: The new pathname. + **/ +RAZOR_EXPORT char *razor_path_add_root(const char *path, const char *root) +{ + if (root && *root) + return razor_concat(root, SKIP_DRIVE_LETTER(path), NULL); + else + return strdup(path); +} + +#if 0 + +/* + * This should work, but for some reason PathCreateFromUrlW() + * treats the percent-encoded bytes as being in CP 850 rather + * than UTF-8 as expected even if we set the codepage. + */ +RAZOR_EXPORT char *razor_path_from_url(const char *url) +{ + UINT saved_cp; + HRESULT result; + DWORD len = MAX_PATH; + wchar_t *url16; + wchar_t path16[MAX_PATH]; + char *path; + + url16 = razor_utf8_to_utf16(url, -1); + + saved_cp = GetConsoleCP(); + SetConsoleCP(CP_UTF8); + + result = PathCreateFromUrlW(url16, path16, &len, NULL); + + SetConsoleCP(saved_cp); + + if (result == S_OK) + path = razor_utf16_to_utf8(path16, len); + else + path = NULL; + + free(url16); + + return path; +} + +#else + +#ifdef MSWIN_API +static int is_ascii_letter(char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} +#endif + +static int xdigit_value(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else + return (c | 0x20) - 'a' + 10; +} + +static int valid_unicode(unsigned unicode) +{ + /* + * Within the U+0000..U+10FFFF range defined by RFC3629 + * but not in the U+D800..U+DFFF range prohibited in UTF-8. + */ + return unicode < 0xD800 || (unicode >= 0xE000 && unicode < 0x110000); +} + +RAZOR_EXPORT char *razor_path_from_url(const char *url) +{ + int continuation_bytes = 0; + char *path, *p; + unsigned char c; + unsigned unicode; + + if (strncmp(url, "file://", 7) == 0) + url += 7; + else + return NULL; + + if (strncmp(url, "localhost/", 10) == 0) + url += 9; + else if (strncmp(url, "/", 1) != 0) + return NULL; + +#ifdef MSWIN_API + /* + * Under MS-Windows, file:///c:/xxx maps to c:/xxx + * Note that PathCreateFromUrl converts / to \ as well. + */ + if (is_ascii_letter(url[1]) && url[2] == ':' && url[3] == '/') + url++; +#endif + + p = path = malloc(strlen(url) + 1); + + while(*url) { + if (*url >= 0x7F || *url < 0x20) { + free(path); + return NULL; + } else if (*url != '%') { + if (continuation_bytes) { + free(path); + return NULL; + } else + *p++ = *url++; + } else if (isxdigit(url[1]) && isxdigit(url[2])) { + c = xdigit_value(url[1]) * 16 + xdigit_value(url[2]); + if (c == '/') { + free(path); + return NULL; + } else if (!continuation_bytes) { + if (c >= 0xF5 || c == 0xC0 || c == 0xC1) { + free(path); + return NULL; + } else if (c >= 0xF0) { + unicode = c & 7; + continuation_bytes = 3; + } else if (c >= 0xE0) { + unicode = c & 3; + continuation_bytes = 2; + } else if (c >= 0xC0) { + unicode = c & 1; + continuation_bytes = 1; + } + } else if ((c & 0xC0) != 0x80) { + free(path); + return NULL; + } else { + unicode <<= 6; + unicode |= (c & 0x3F); + + if (!--continuation_bytes && + !valid_unicode(unicode)) { + free(path); + return NULL; + } + } + + *p++ = c; + url += 3; + } else { + free(path); + return NULL; + } + } + + if (continuation_bytes) { + free(path); + return NULL; + } + + *p++ = '\0'; + + return realloc(path, p - path); +} + +#endif /* 0 */ diff --git a/librazor/test-pfu.c b/librazor/test-pfu.c new file mode 100644 index 0000000..0414b38 --- /dev/null +++ b/librazor/test-pfu.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2014 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#ifdef MSWIN_API +#include +#endif +#include "razor.h" + +int is_ascii_letter(char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +int is_slash(char c) +{ + return c == '/' || c == '\\'; +} + +const char *mswin_path(const char *path) +{ + if (path == NULL) + return NULL; + + if (path[0] == '/' && is_ascii_letter(path[1]) && path[2] == ':' && + path[3] == '/') + path++; + + return path; +} + +int path_cmp(const char *p1, const char *p2) +{ +#ifdef MSWIN_API + while(*p1 && *p2) { + if (*p1 == *p2 || is_slash(*p1) && is_slash(*p2)) { + p1++; + p2++; + } else + break; + } + + return *p1 || *p2; +#else + return strcmp(p1, p2); +#endif +} + +int test_pfu(const char *url, const char *path) +{ + char *s; + int r; + + s = razor_path_from_url(url); + +#ifdef MSWIN_API + path = mswin_path(path); +#endif + + if (s && path) + r = path_cmp(s, path); + else + r = (s != path); + + if (r) { + fprintf(stderr, "Fail: razor_path_from_url(\"%s\")", url); + if (s) + fprintf(stderr, " returns \"%s\", expected", s); + else + fprintf(stderr, " returns NULL, expected"); + if (path) + fprintf(stderr, " \"%s\"\n", path); + else + fprintf(stderr, " NULL\n"); + } + + free(s); + + return r; +} + +#ifdef MSWIN_API +UINT saved_cp; + +void cleanup_on_exit(void) +{ + SetConsoleOutputCP(saved_cp); +} +#endif + +int main(int argc, char *argv[]) +{ + int r = 0; + +#ifdef MSWIN_API + atexit(cleanup_on_exit); + saved_cp = GetConsoleOutputCP(); + SetConsoleOutputCP(CP_UTF8); +#endif + + r |= test_pfu("file://localhost/etc/fstab", "/etc/fstab"); + r |= test_pfu("file:///etc/fstab", "/etc/fstab"); + r |= test_pfu("file://localhost/c:/WINDOWS/clock.avi", + "/c:/WINDOWS/clock.avi"); + r |= test_pfu("file:///c:/WINDOWS/clock.avi", + "/c:/WINDOWS/clock.avi"); + r |= test_pfu("file:///path/to/the%20file.txt", + "/path/to/the file.txt"); + r |= test_pfu("file:///home/s%C3%A9bastien", "/home/sébastien"); + r |= test_pfu("file:///home/luk%C3%A1%C5%A1", "/home/lukáš"); + r |= test_pfu("file:///var/log/22%20%e0%b8%aa%e0%b8%b4%e0%b8%87%e0%b8%ab%e0%b8%b2%e0%b8%84%e0%b8%a1%202014", + "/var/log/22 สิงหาคม 2014"); + + exit(r ? 1 : 0); +} -- 1.7.1