From: Amos Jeffries Date: Tue, 18 Feb 2014 08:46:49 +0000 (-0700) Subject: Bug 4001: remove use of strsep() X-Git-Tag: SQUID_3_4_4~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=638ce3f5b8f644ba694a52ed2097b2b1cfb3635b;p=thirdparty%2Fsquid.git Bug 4001: remove use of strsep() The strsep() function is not defined by POSIX. Additionally auto-tools has been having some obscure issues detecting or linking the provided implementation into libcompat on Windows and Solaris respectively. Which are the two known OS requiring it. Investigation of its use in Squid revealed that it can be replaced with strcspan() which is both portable and more efficient since it also removes the need for several strdup()/free() operations used to protect Squid from strsep() memory fiddling. --- diff --git a/CREDITS b/CREDITS index cf99ccce23..93ea422dd5 100644 --- a/CREDITS +++ b/CREDITS @@ -484,28 +484,6 @@ helpers/negotiate_auth/kerberos/ * ============================================================================== -compat/strsep.h, lib/strsep.c - - * Copyright (C) 2004 Free Software Foundation, Inc. - * Written by Yoann Vandoorselaere - * - * The file 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. - * - * This file 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 this file; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - -============================================================================== - helpers/external_acl/kerberos_ldap_group/support_ldap.cc /* get_attributes is partly from OpenLDAP Software . diff --git a/compat/Makefile.am b/compat/Makefile.am index 70cf427ad5..e988564be3 100644 --- a/compat/Makefile.am +++ b/compat/Makefile.am @@ -39,7 +39,6 @@ libcompat_squid_la_SOURCES = \ stdio.h \ stdvarargs.h \ strnstr.cc \ - strsep.h \ strtoll.h \ strnrchr.h \ strnrchr.c \ diff --git a/compat/os/mswindows.h b/compat/os/mswindows.h index cdc53dc507..a038d13d10 100644 --- a/compat/os/mswindows.h +++ b/compat/os/mswindows.h @@ -962,7 +962,5 @@ void syslog(int priority, const char *fmt, ...); /* prototypes */ void WIN32_maperror(unsigned long WIN32_oserrno); -#include "compat/strsep.h" - #endif /* _SQUID_WINDOWS_ */ #endif /* SQUID_OS_MSWINDOWS_H */ diff --git a/compat/os/solaris.h b/compat/os/solaris.h index 793e266249..a62cc2cf47 100644 --- a/compat/os/solaris.h +++ b/compat/os/solaris.h @@ -101,8 +101,5 @@ SQUIDCEXTERN int gethostname(char *, int); #define _PATH_DEVNULL "/dev/null" #endif -/* Solaris 10 does not define strsep() */ -#include "compat/strsep.h" - #endif /* _SQUID_SOLARIS_ */ #endif /* SQUID_OS_SOALRIS_H */ diff --git a/compat/strsep.c b/compat/strsep.c deleted file mode 100644 index 5fbd788209..0000000000 --- a/compat/strsep.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2004 Free Software Foundation, Inc. - * Written by Yoann Vandoorselaere - * - * The file 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. - * - * This file 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 this file; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#include "squid.h" -#include "compat/strsep.h" - -#include - -char * -strsep(char **stringp, const char *delim) -{ - char *start = *stringp; - char *ptr; - - if (!start) - return NULL; - - if (!*delim) - ptr = start + strlen (start); - else { - ptr = strpbrk (start, delim); - if (!ptr) { - *stringp = NULL; - return start; - } - } - - *ptr = '\0'; - *stringp = ptr + 1; - - return start; -} diff --git a/compat/strsep.h b/compat/strsep.h deleted file mode 100644 index 4181454b0f..0000000000 --- a/compat/strsep.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 2004 Free Software Foundation, Inc. - * Written by Yoann Vandoorselaere - * - * The file 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. - * - * This file 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 this file; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ -#ifndef GNULIB_STRSEP_H_ -#define GNULIB_STRSEP_H_ - -#if HAVE_STRSEP - -/* - * Get strsep() declaration. - */ -#if HAVE_STRING_H -#include -#endif - -#else - -/** - *\par - * Searches the next delimiter (char listed in DELIM) starting at *STRINGP. - * If one is found, it is overwritten with a NULL, and *STRINGP is advanced - * to point to the next char after it. Otherwise, *STRINGP is set to NULL. - * If *STRINGP was already NULL, nothing happens. - * Returns the old value of *STRINGP. - * - *\par - * This is a variant of strtok() that is multithread-safe and supports - * empty fields. - * - * \note Caveat: It modifies the original string. - * \note Caveat: These functions cannot be used on constant strings. - * \note Caveat: The identity of the delimiting character is lost. - * \note Caveat: It doesn't work with multibyte strings unless all of the delimiter - * characters are ASCII characters < 0x30. - * - * See also strtok_r(). - */ -SQUIDCEXTERN char *strsep(char **stringp, const char *delim); - -#endif /* HAVE_STRSEP */ -#endif /* GNULIB_STRSEP_H_ */ diff --git a/configure.ac b/configure.ac index 6e0702b3ed..3e027125f5 100644 --- a/configure.ac +++ b/configure.ac @@ -3124,7 +3124,6 @@ AC_REPLACE_FUNCS(\ getnameinfo \ psignal \ strerror \ - strsep \ strtoll \ tempnam \ ) diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 6bec56143d..25af575080 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -59,7 +59,7 @@ static mib_tree_entry * snmpAddNodeStr(const char *base_str, int o, oid_ParseFn static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType, int children,...); static oid *snmpCreateOid(int length,...); mib_tree_entry * snmpLookupNodeStr(mib_tree_entry *entry, const char *str); -int snmpCreateOidFromStr(const char *str, oid **name, int *nl); +bool snmpCreateOidFromStr(const char *str, oid **name, int *nl); SQUIDCEXTERN void (*snmplib_debug_hook) (int, char *); static oid *static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn); static oid *time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn); @@ -951,26 +951,29 @@ snmpLookupNodeStr(mib_tree_entry *root, const char *str) return e; } -int +bool snmpCreateOidFromStr(const char *str, oid **name, int *nl) { char const *delim = "."; - char *p; *name = NULL; *nl = 0; - char *s = xstrdup(str); - char *s_ = s; + const char *s = str; /* Parse the OID string into oid bits */ - while ( (p = strsep(&s_, delim)) != NULL) { + while (size_t len = strcspn(s, delim)) { *name = (oid*)xrealloc(*name, sizeof(oid) * ((*nl) + 1)); - (*name)[*nl] = atoi(p); + (*name)[*nl] = atoi(s); // stops at the '.' delimiter ++(*nl); + // exit with true when the last octet has been parsed + if (s[len] == '\0') + return true; + s += len+1; } - xfree(s); - return 1; + // if we aborted before the lst octet was found, return false. + safe_free(name); + return false; } /* diff --git a/src/wccp2.cc b/src/wccp2.cc index 23b9e63da1..954088c62f 100644 --- a/src/wccp2.cc +++ b/src/wccp2.cc @@ -38,7 +38,6 @@ #include "comm.h" #include "comm/Connection.h" #include "comm/Loops.h" -#include "compat/strsep.h" #include "event.h" #include "ip/Address.h" #include "md5.h" @@ -2206,82 +2205,72 @@ check_null_wccp2_service(void *v) static int parse_wccp2_service_flags(char *flags) { - char *tmp, *tmp2; - char *flag; - int retflag = 0; - - if (!flags) { + if (!flags) return 0; - } - tmp = xstrdup(flags); - tmp2 = tmp; + char *flag = flags; + int retflag = 0; - flag = strsep(&tmp2, ","); + while (size_t len = strcspn(flag, ",")) { - while (flag) { - if (strcmp(flag, "src_ip_hash") == 0) { + if (strncmp(flag, "src_ip_hash", len) == 0) { retflag |= WCCP2_SERVICE_SRC_IP_HASH; - } else if (strcmp(flag, "dst_ip_hash") == 0) { + } else if (strncmp(flag, "dst_ip_hash", len) == 0) { retflag |= WCCP2_SERVICE_DST_IP_HASH; - } else if (strcmp(flag, "source_port_hash") == 0) { + } else if (strncmp(flag, "source_port_hash", len) == 0) { retflag |= WCCP2_SERVICE_SRC_PORT_HASH; - } else if (strcmp(flag, "dst_port_hash") == 0) { + } else if (strncmp(flag, "dst_port_hash", len) == 0) { retflag |= WCCP2_SERVICE_DST_PORT_HASH; - } else if (strcmp(flag, "ports_source") == 0) { + } else if (strncmp(flag, "ports_source", len) == 0) { retflag |= WCCP2_SERVICE_PORTS_SOURCE; - } else if (strcmp(flag, "src_ip_alt_hash") == 0) { + } else if (strncmp(flag, "src_ip_alt_hash", len) == 0) { retflag |= WCCP2_SERVICE_SRC_IP_ALT_HASH; - } else if (strcmp(flag, "dst_ip_alt_hash") == 0) { + } else if (strncmp(flag, "dst_ip_alt_hash", len) == 0) { retflag |= WCCP2_SERVICE_DST_IP_ALT_HASH; - } else if (strcmp(flag, "src_port_alt_hash") == 0) { + } else if (strncmp(flag, "src_port_alt_hash", len) == 0) { retflag |= WCCP2_SERVICE_SRC_PORT_ALT_HASH; - } else if (strcmp(flag, "dst_port_alt_hash") == 0) { + } else if (strncmp(flag, "dst_port_alt_hash", len) == 0) { retflag |= WCCP2_SERVICE_DST_PORT_ALT_HASH; } else { + flag[len] = '\0'; fatalf("Unknown wccp2 service flag: %s\n", flag); } - flag = strsep(&tmp2, ","); + if (flag[len] == '\0') + break; + + flag += len+1; } - xfree(tmp); return retflag; } static void parse_wccp2_service_ports(char *options, int portlist[]) { - int i = 0; - int p; - char *tmp, *tmp2, *port; - if (!options) { return; } - tmp = xstrdup(options); - tmp2 = tmp; - - port = strsep(&tmp2, ","); + int i = 0; + char *tmp = options; - while (port && i < WCCP2_NUMPORTS) { - p = xatoi(port); + while (size_t len = strcspn(tmp, ",")) { + if (i >= WCCP2_NUMPORTS) { + fatalf("parse_wccp2_service_ports: too many ports (maximum: 8) in list '%s'\n", options); + } + int p = xatoi(tmp); if (p < 1 || p > 65535) { - fatalf("parse_wccp2_service_ports: port value '%s' isn't valid (1..65535)\n", port); + fatalf("parse_wccp2_service_ports: port value '%s' isn't valid (1..65535)\n", tmp); } portlist[i] = p; ++i; - port = strsep(&tmp2, ","); - } - - if (i == WCCP2_NUMPORTS && port) { - fatalf("parse_wccp2_service_ports: too many ports (maximum: 8) in list '%s'\n", options); + if (tmp[len] == '\0') + return; + tmp += len+1; } - - xfree(tmp); } void