Richard W.M. Jones
2020-May-19 15:42 UTC
[Libguestfs] [PATCH nbdkit] common/include: Add locale-safe ascii_strcasecmp and ascii_strncasecmp.
These are derived from the FreeBSD functions here: https://github.com/freebsd/freebsd/blob/master/sys/libkern/strcasecmp.c Thanks: Eric Blake. --- common/include/Makefile.am | 6 +++ common/include/ascii-ctype.h | 6 +++ common/include/ascii-string.h | 77 ++++++++++++++++++++++++++++ common/include/test-ascii-string.c | 79 +++++++++++++++++++++++++++++ server/main.c | 8 +-- server/public.c | 21 ++++---- plugins/curl/curl.c | 7 +-- plugins/info/info.c | 17 ++++--- plugins/nbd/nbd.c | 8 +-- plugins/partitioning/partitioning.c | 10 ++-- plugins/sh/call.c | 25 ++++----- plugins/sh/methods.c | 27 +++++----- filters/ip/ip.c | 13 ++--- .gitignore | 1 + 14 files changed, 243 insertions(+), 62 deletions(-) diff --git a/common/include/Makefile.am b/common/include/Makefile.am index aa515702..dd1f871a 100644 --- a/common/include/Makefile.am +++ b/common/include/Makefile.am @@ -35,6 +35,7 @@ include $(top_srcdir)/common-rules.mk # plugins and/or filters. They are not installed. EXTRA_DIST = \ ascii-ctype.h \ + ascii-string.h \ byte-swapping.h \ exit-with-parent.h \ get-current-dir-name.h \ @@ -52,6 +53,7 @@ EXTRA_DIST = \ TESTS = \ test-ascii-ctype \ + test-ascii-string \ test-byte-swapping \ test-current-dir-name \ test-isaligned \ @@ -68,6 +70,10 @@ test_ascii_ctype_SOURCES = test-ascii-ctype.c ascii-ctype.h test_ascii_ctype_CPPFLAGS = -I$(srcdir) test_ascii_ctype_CFLAGS = $(WARNINGS_CFLAGS) +test_ascii_string_SOURCES = test-ascii-string.c ascii-string.h +test_ascii_string_CPPFLAGS = -I$(srcdir) +test_ascii_string_CFLAGS = $(WARNINGS_CFLAGS) + test_byte_swapping_SOURCES = test-byte-swapping.c byte-swapping.h test_byte_swapping_CPPFLAGS = -I$(srcdir) test_byte_swapping_CFLAGS = $(WARNINGS_CFLAGS) diff --git a/common/include/ascii-ctype.h b/common/include/ascii-ctype.h index 5e8bf237..a700563e 100644 --- a/common/include/ascii-ctype.h +++ b/common/include/ascii-ctype.h @@ -49,6 +49,9 @@ #define ascii_isspace(c) \ ((c) == '\t' || (c) == '\n' || (c) == '\f' || (c) == '\r' || (c) == ' ') +#define ascii_isupper(c) \ + ((c) >= 'A' && (c) <= 'Z') + #define ascii_isxdigit(c) \ ((c) == '0' || (c) == '1' || (c) == '2' || (c) == '3' || (c) == '4' || \ (c) == '5' || (c) == '6' || (c) == '7' || (c) == '8' || (c) == '9' || \ @@ -57,4 +60,7 @@ (c) == 'A' || (c) == 'B' || (c) == 'C' || \ (c) == 'D' || (c) == 'E' || (c) == 'F') +#define ascii_tolower(c) \ + (ascii_isupper ((c)) ? (c) - 'A' + 'a' : (c)) + #endif /* NBDKIT_ASCII_CTYPE_H */ diff --git a/common/include/ascii-string.h b/common/include/ascii-string.h new file mode 100644 index 00000000..0a60d5f4 --- /dev/null +++ b/common/include/ascii-string.h @@ -0,0 +1,77 @@ +/* nbdkit + * Copyright (C) 2013-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Case insensitive string comparison functions (like strcasecmp, + * strncasecmp) which work correctly in any locale. They can only be + * used for comparison when one or both strings is 7 bit ASCII. + */ + +#ifndef NBDKIT_ASCII_STRING_H +#define NBDKIT_ASCII_STRING_H + +#include "ascii-ctype.h" + +static inline int +ascii_strcasecmp (const char *s1, const char *s2) +{ + const unsigned char *us1 = (const unsigned char *)s1; + const unsigned char *us2 = (const unsigned char *)s2; + + while (ascii_tolower (*us1) == ascii_tolower (*us2)) { + if (*us1++ == '\0') + return 0; + us2++; + } + + return ascii_tolower (*us1) - ascii_tolower (*us2); +} + +static inline int +ascii_strncasecmp (const char *s1, const char *s2, size_t n) +{ + if (n != 0) { + const unsigned char *us1 = (const unsigned char *)s1; + const unsigned char *us2 = (const unsigned char *)s2; + + do { + if (ascii_tolower (*us1) != ascii_tolower (*us2)) + return ascii_tolower (*us1) - ascii_tolower (*us2); + if (*us1++ == '\0') + break; + us2++; + } while (--n != 0); + } + + return 0; +} + +#endif /* NBDKIT_ASCII_STRING_H */ diff --git a/common/include/test-ascii-string.c b/common/include/test-ascii-string.c new file mode 100644 index 00000000..0fa4a483 --- /dev/null +++ b/common/include/test-ascii-string.c @@ -0,0 +1,79 @@ +/* nbdkit + * Copyright (C) 2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "ascii-string.h" + +int +main (void) +{ + assert (ascii_strcasecmp ("", "") == 0); + assert (ascii_strcasecmp ("a", "a") == 0); + assert (ascii_strcasecmp ("abc", "abc") == 0); + assert (ascii_strcasecmp ("a", "b") < 0); + assert (ascii_strcasecmp ("b", "a") > 0); + assert (ascii_strcasecmp ("aa", "a") > 0); + + /* Second string contains Turkish dotless lowercase letter ı. */ + assert (ascii_strcasecmp ("hi", "hı") != 0); + + /* Check that we got our rounding behaviour correct. */ + assert (ascii_strcasecmp ("\x1", "\x7f") < 0); + assert (ascii_strcasecmp ("\x1", "\x80") < 0); + assert (ascii_strcasecmp ("\x1", "\x81") < 0); + assert (ascii_strcasecmp ("\x1", "\xff") < 0); + + assert (ascii_strncasecmp ("", "", 0) == 0); + assert (ascii_strncasecmp ("a", "a", 1) == 0); + assert (ascii_strncasecmp ("abc", "abc", 3) == 0); + assert (ascii_strncasecmp ("abc", "def", 0) == 0); + assert (ascii_strncasecmp ("abc", "abd", 2) == 0); + assert (ascii_strncasecmp ("a", "b", 1) < 0); + assert (ascii_strncasecmp ("b", "a", 1) > 0); + assert (ascii_strncasecmp ("aa", "a", 2) > 0); + assert (ascii_strncasecmp ("aa", "a", 100) > 0); + + assert (ascii_strncasecmp ("hi", "hı", 1) == 0); + assert (ascii_strncasecmp ("hi", "hı", 2) != 0); + + assert (ascii_strncasecmp ("\x1", "\x7f", 1) < 0); + assert (ascii_strncasecmp ("\x1", "\x80", 1) < 0); + assert (ascii_strncasecmp ("\x1", "\x81", 1) < 0); + assert (ascii_strncasecmp ("\x1", "\xff", 1) < 0); + + exit (EXIT_SUCCESS); +} diff --git a/server/main.c b/server/main.c index 9dd9d400..feff57a3 100644 --- a/server/main.c +++ b/server/main.c @@ -59,6 +59,8 @@ #include <dlfcn.h> +#include "ascii-string.h" + #include "internal.h" #include "nbd-protocol.h" #include "options.h" @@ -300,9 +302,9 @@ main (int argc, char *argv[]) case TLS_OPTION: tls_set_on_cli = true; - if (strcasecmp (optarg, "require") == 0 || - strcasecmp (optarg, "required") == 0 || - strcasecmp (optarg, "force") == 0) + if (ascii_strcasecmp (optarg, "require") == 0 || + ascii_strcasecmp (optarg, "required") == 0 || + ascii_strcasecmp (optarg, "force") == 0) tls = 2; else { tls = nbdkit_parse_bool (optarg); diff --git a/server/public.c b/server/public.c index d1925c9f..bcf1a3a2 100644 --- a/server/public.c +++ b/server/public.c @@ -52,6 +52,7 @@ #include <sys/socket.h> #include "ascii-ctype.h" +#include "ascii-string.h" #include "get-current-dir-name.h" #include "internal.h" @@ -385,19 +386,19 @@ int nbdkit_parse_bool (const char *str) { if (!strcmp (str, "1") || - !strcasecmp (str, "true") || - !strcasecmp (str, "t") || - !strcasecmp (str, "yes") || - !strcasecmp (str, "y") || - !strcasecmp (str, "on")) + !ascii_strcasecmp (str, "true") || + !ascii_strcasecmp (str, "t") || + !ascii_strcasecmp (str, "yes") || + !ascii_strcasecmp (str, "y") || + !ascii_strcasecmp (str, "on")) return 1; if (!strcmp (str, "0") || - !strcasecmp (str, "false") || - !strcasecmp (str, "f") || - !strcasecmp (str, "no") || - !strcasecmp (str, "n") || - !strcasecmp (str, "off")) + !ascii_strcasecmp (str, "false") || + !ascii_strcasecmp (str, "f") || + !ascii_strcasecmp (str, "no") || + !ascii_strcasecmp (str, "n") || + !ascii_strcasecmp (str, "off")) return 0; nbdkit_error ("could not decipher boolean (%s)", str); diff --git a/plugins/curl/curl.c b/plugins/curl/curl.c index f4afc826..b3059ed4 100644 --- a/plugins/curl/curl.c +++ b/plugins/curl/curl.c @@ -58,6 +58,7 @@ #include "cleanup.h" #include "ascii-ctype.h" +#include "ascii-string.h" static const char *url = NULL; /* required */ @@ -477,8 +478,8 @@ curl_open (int readonly) #endif nbdkit_debug ("content length: %" PRIi64, h->exportsize); - if (strncasecmp (url, "http://", strlen ("http://")) == 0 || - strncasecmp (url, "https://", strlen ("https://")) == 0) { + if (ascii_strncasecmp (url, "http://", strlen ("http://")) == 0 || + ascii_strncasecmp (url, "https://", strlen ("https://")) == 0) { if (!h->accept_range) { nbdkit_error ("server does not support 'range' (byte range) requests"); goto err; @@ -562,7 +563,7 @@ header_cb (void *ptr, size_t size, size_t nmemb, void *opaque) const char *bytes = "bytes"; if (realsize >= strlen (accept_ranges) && - strncasecmp (header, accept_ranges, strlen (accept_ranges)) == 0) { + ascii_strncasecmp (header, accept_ranges, strlen (accept_ranges)) == 0) { const char *p = strchr (header, ':') + 1; /* Skip whitespace between the header name and value. */ diff --git a/plugins/info/info.c b/plugins/info/info.c index 6505ffbb..33c4facd 100644 --- a/plugins/info/info.c +++ b/plugins/info/info.c @@ -49,6 +49,7 @@ #include <nbdkit-plugin.h> +#include "ascii-string.h" #include "byte-swapping.h" #include "tvdiff.h" @@ -76,12 +77,12 @@ static int info_config (const char *key, const char *value) { if (strcmp (key, "mode") == 0) { - if (strcasecmp (value, "exportname") == 0 || - strcasecmp (value, "export-name") == 0) { + if (ascii_strcasecmp (value, "exportname") == 0 || + ascii_strcasecmp (value, "export-name") == 0) { mode = MODE_EXPORTNAME; } - else if (strcasecmp (value, "base64exportname") == 0 || - strcasecmp (value, "base64-export-name") == 0) { + else if (ascii_strcasecmp (value, "base64exportname") == 0 || + ascii_strcasecmp (value, "base64-export-name") == 0) { #ifdef HAVE_BASE64 mode = MODE_BASE64EXPORTNAME; #else @@ -89,13 +90,13 @@ info_config (const char *key, const char *value) return -1; #endif } - else if (strcasecmp (value, "address") == 0) + else if (ascii_strcasecmp (value, "address") == 0) mode = MODE_ADDRESS; - else if (strcasecmp (value, "time") == 0) + else if (ascii_strcasecmp (value, "time") == 0) mode = MODE_TIME; - else if (strcasecmp (value, "uptime") == 0) + else if (ascii_strcasecmp (value, "uptime") == 0) mode = MODE_UPTIME; - else if (strcasecmp (value, "conntime") == 0) + else if (ascii_strcasecmp (value, "conntime") == 0) mode = MODE_CONNTIME; else { nbdkit_error ("unknown mode: '%s'", value); diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c index 0ea2a4a2..b21590e6 100644 --- a/plugins/nbd/nbd.c +++ b/plugins/nbd/nbd.c @@ -52,6 +52,8 @@ #define NBDKIT_API_VERSION 2 #include <nbdkit-plugin.h> + +#include "ascii-string.h" #include "byte-swapping.h" #include "cleanup.h" #include "utils.h" @@ -152,9 +154,9 @@ nbdplug_config (const char *key, const char *value) shared = r; } else if (strcmp (key, "tls") == 0) { - if (strcasecmp (value, "require") == 0 || - strcasecmp (value, "required") == 0 || - strcasecmp (value, "force") == 0) + if (ascii_strcasecmp (value, "require") == 0 || + ascii_strcasecmp (value, "required") == 0 || + ascii_strcasecmp (value, "force") == 0) tls = LIBNBD_TLS_REQUIRE; else { r = nbdkit_parse_bool (value); diff --git a/plugins/partitioning/partitioning.c b/plugins/partitioning/partitioning.c index 09e17e3a..5e963026 100644 --- a/plugins/partitioning/partitioning.c +++ b/plugins/partitioning/partitioning.c @@ -48,6 +48,7 @@ #include <nbdkit-plugin.h> +#include "ascii-string.h" #include "byte-swapping.h" #include "isaligned.h" #include "iszero.h" @@ -172,9 +173,10 @@ partitioning_config (const char *key, const char *value) } } else if (strcmp (key, "partition-type") == 0) { - if (strcasecmp (value, "mbr") == 0 || strcasecmp (value, "dos") == 0) + if (ascii_strcasecmp (value, "mbr") == 0 || + ascii_strcasecmp (value, "dos") == 0) parttype = PARTTYPE_MBR; - else if (strcasecmp (value, "gpt") == 0) + else if (ascii_strcasecmp (value, "gpt") == 0) parttype = PARTTYPE_GPT; else { nbdkit_error ("unknown partition-type: %s", value); @@ -205,13 +207,13 @@ partitioning_config (const char *key, const char *value) alignment = r; } else if (strcmp (key, "mbr-id") == 0) { - if (strcasecmp (value, "default") == 0) + if (ascii_strcasecmp (value, "default") == 0) mbr_id = DEFAULT_MBR_ID; else if (nbdkit_parse_uint8_t ("mbr-id", value, &mbr_id) == -1) return -1; } else if (strcmp (key, "type-guid") == 0) { - if (strcasecmp (value, "default") == 0) + if (ascii_strcasecmp (value, "default") == 0) parse_guid (DEFAULT_TYPE_GUID, type_guid); else if (parse_guid (value, type_guid) == -1) { nbdkit_error ("could not validate GUID: %s", value); diff --git a/plugins/sh/call.c b/plugins/sh/call.c index 741022b6..aa0fe8a0 100644 --- a/plugins/sh/call.c +++ b/plugins/sh/call.c @@ -48,6 +48,7 @@ #include <nbdkit-plugin.h> #include "ascii-ctype.h" +#include "ascii-string.h" #include "cleanup.h" #include "utils.h" @@ -383,48 +384,48 @@ handle_script_error (const char *argv0, char *ebuf, size_t len) } /* Recognize the errno values that match NBD protocol errors */ - if (strncasecmp (ebuf, "EPERM", 5) == 0) { + if (ascii_strncasecmp (ebuf, "EPERM", 5) == 0) { err = EPERM; skip = 5; } - else if (strncasecmp (ebuf, "EIO", 3) == 0) { + else if (ascii_strncasecmp (ebuf, "EIO", 3) == 0) { err = EIO; skip = 3; } - else if (strncasecmp (ebuf, "ENOMEM", 6) == 0) { + else if (ascii_strncasecmp (ebuf, "ENOMEM", 6) == 0) { err = ENOMEM; skip = 6; } - else if (strncasecmp (ebuf, "EINVAL", 6) == 0) { + else if (ascii_strncasecmp (ebuf, "EINVAL", 6) == 0) { err = EINVAL; skip = 6; } - else if (strncasecmp (ebuf, "ENOSPC", 6) == 0) { + else if (ascii_strncasecmp (ebuf, "ENOSPC", 6) == 0) { err = ENOSPC; skip = 6; } - else if (strncasecmp (ebuf, "EOVERFLOW", 9) == 0) { + else if (ascii_strncasecmp (ebuf, "EOVERFLOW", 9) == 0) { err = EOVERFLOW; skip = 9; } - else if (strncasecmp (ebuf, "ESHUTDOWN", 9) == 0) { + else if (ascii_strncasecmp (ebuf, "ESHUTDOWN", 9) == 0) { err = ESHUTDOWN; skip = 9; } - else if (strncasecmp (ebuf, "ENOTSUP", 7) == 0) { + else if (ascii_strncasecmp (ebuf, "ENOTSUP", 7) == 0) { err = ENOTSUP; skip = 7; } - else if (strncasecmp (ebuf, "EOPNOTSUPP", 10) == 0) { + else if (ascii_strncasecmp (ebuf, "EOPNOTSUPP", 10) == 0) { err = EOPNOTSUPP; skip = 10; } /* Other errno values that server/protocol.c treats specially */ - else if (strncasecmp (ebuf, "EROFS", 5) == 0) { + else if (ascii_strncasecmp (ebuf, "EROFS", 5) == 0) { err = EROFS; skip = 5; } - else if (strncasecmp (ebuf, "EDQUOT", 6) == 0) { + else if (ascii_strncasecmp (ebuf, "EDQUOT", 6) == 0) { #ifdef EDQUOT err = EDQUOT; #else @@ -432,7 +433,7 @@ handle_script_error (const char *argv0, char *ebuf, size_t len) #endif skip = 6; } - else if (strncasecmp (ebuf, "EFBIG", 5) == 0) { + else if (ascii_strncasecmp (ebuf, "EFBIG", 5) == 0) { err = EFBIG; skip = 5; } diff --git a/plugins/sh/methods.c b/plugins/sh/methods.c index 5a7dfe05..10cd4100 100644 --- a/plugins/sh/methods.c +++ b/plugins/sh/methods.c @@ -45,6 +45,7 @@ #include <nbdkit-plugin.h> #include "cleanup.h" +#include "ascii-string.h" #include "call.h" #include "methods.h" @@ -105,16 +106,16 @@ sh_thread_model (void) case OK: if (slen > 0 && s[slen-1] == '\n') s[slen-1] = '\0'; - if (strcasecmp (s, "parallel") == 0) + if (ascii_strcasecmp (s, "parallel") == 0) r = NBDKIT_THREAD_MODEL_PARALLEL; - else if (strcasecmp (s, "serialize_requests") == 0 || - strcasecmp (s, "serialize-requests") == 0) + else if (ascii_strcasecmp (s, "serialize_requests") == 0 || + ascii_strcasecmp (s, "serialize-requests") == 0) r = NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS; - else if (strcasecmp (s, "serialize_all_requests") == 0 || - strcasecmp (s, "serialize-all-requests") == 0) + else if (ascii_strcasecmp (s, "serialize_all_requests") == 0 || + ascii_strcasecmp (s, "serialize-all-requests") == 0) r = NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS; - else if (strcasecmp (s, "serialize_connections") == 0 || - strcasecmp (s, "serialize-connections") == 0) + else if (ascii_strcasecmp (s, "serialize_connections") == 0 || + ascii_strcasecmp (s, "serialize-connections") == 0) r = NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS; else { nbdkit_debug ("%s: ignoring unrecognized thread model: %s", @@ -545,11 +546,11 @@ sh_can_fua (void *handle) case OK: if (slen > 0 && s[slen-1] == '\n') s[slen-1] = '\0'; - if (strcasecmp (s, "none") == 0) + if (ascii_strcasecmp (s, "none") == 0) r = NBDKIT_FUA_NONE; - else if (strcasecmp (s, "emulate") == 0) + else if (ascii_strcasecmp (s, "emulate") == 0) r = NBDKIT_FUA_EMULATE; - else if (strcasecmp (s, "native") == 0) + else if (ascii_strcasecmp (s, "native") == 0) r = NBDKIT_FUA_NATIVE; else { nbdkit_error ("%s: could not parse output from %s method: %s", @@ -600,11 +601,11 @@ sh_can_cache (void *handle) case OK: if (slen > 0 && s[slen-1] == '\n') s[slen-1] = '\0'; - if (strcasecmp (s, "none") == 0) + if (ascii_strcasecmp (s, "none") == 0) r = NBDKIT_CACHE_NONE; - else if (strcasecmp (s, "emulate") == 0) + else if (ascii_strcasecmp (s, "emulate") == 0) r = NBDKIT_CACHE_EMULATE; - else if (strcasecmp (s, "native") == 0) + else if (ascii_strcasecmp (s, "native") == 0) r = NBDKIT_CACHE_NATIVE; else { nbdkit_error ("%s: could not parse output from %s method: %s", diff --git a/filters/ip/ip.c b/filters/ip/ip.c index 4f6e32e4..26a34d6e 100644 --- a/filters/ip/ip.c +++ b/filters/ip/ip.c @@ -45,6 +45,7 @@ #include <nbdkit-filter.h> +#include "ascii-string.h" #include "cleanup.h" /* -D ip.rules=1 to enable debugging of rules and rule matching. */ @@ -199,20 +200,20 @@ parse_rule (const char *paramname, assert (n > 0); - if (n == 3 && (strncasecmp (value, "all", 3) == 0 || - strncasecmp (value, "any", 3) == 0)) { + if (n == 3 && (ascii_strncasecmp (value, "all", 3) == 0 || + ascii_strncasecmp (value, "any", 3) == 0)) { new_rule->type = ANY; return 0; } - if (n == 7 && (strncasecmp (value, "allipv4", 7) == 0 || - strncasecmp (value, "anyipv4", 7) == 0)) { + if (n == 7 && (ascii_strncasecmp (value, "allipv4", 7) == 0 || + ascii_strncasecmp (value, "anyipv4", 7) == 0)) { new_rule->type = ANYV4; return 0; } - if (n == 7 && (strncasecmp (value, "allipv6", 7) == 0 || - strncasecmp (value, "anyipv6", 7) == 0)) { + if (n == 7 && (ascii_strncasecmp (value, "allipv6", 7) == 0 || + ascii_strncasecmp (value, "anyipv6", 7) == 0)) { new_rule->type = ANYV6; return 0; } diff --git a/.gitignore b/.gitignore index dd510e46..3157a8d3 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ plugins/*/*.3 /autom4te.cache /common/bitmap/test-bitmap /common/include/test-ascii-ctype +/common/include/test-ascii-string /common/include/test-byte-swapping /common/include/test-current-dir-name /common/include/test-isaligned -- 2.25.0
Eric Blake
2020-May-19 16:14 UTC
Re: [Libguestfs] [PATCH nbdkit] common/include: Add locale-safe ascii_strcasecmp and ascii_strncasecmp.
On 5/19/20 10:42 AM, Richard W.M. Jones wrote:> These are derived from the FreeBSD functions here: > https://github.com/freebsd/freebsd/blob/master/sys/libkern/strcasecmp.c > > Thanks: Eric Blake. > ---LGTM. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org