Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp579787imm; Mon, 21 May 2018 10:39:34 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqdq9ISi/9Qa3O8tUxrnNTy4ILC+dyflyfPCKYwu1RjJCyM6FasggzH/hPMFkmL6axJV9sr X-Received: by 2002:a17:902:bc4c:: with SMTP id t12-v6mr21514464plz.331.1526924374176; Mon, 21 May 2018 10:39:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526924374; cv=none; d=google.com; s=arc-20160816; b=cE1JlxQ++me9G6Suszh81pdlLM8c/nAIY4bNzpa4jlnelUu+3KqZRRTpNaT/w6MdCf islFpK9aUFwwztHI2+wBx9/ZGqFH72KVm7hw2dQIuzBJqmrrmuB+Bq3rtzo7IJjeU8en VW1zXYBs84s6Vkv6ri9m2aTyjy7AWLtNVj9QNCsOdmh9TDXg9MpQqgY35AoBiYG0FhGM 2xi5wSOdP4wld6spPmZCssC2dlbnLAH49vuzXySj0kDD4hSFH3nbRDaNj0hF8YIPXuAe ZflTOpr8C+SK1mitE2BywSTa7DGGiBjlAkIlSe/FTbd9KXxLNEgzUcuQiNylcQR6CPGf zw9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=Ri8OfKFGPSZI4aAnvvLfDBES7Xz7blRu/lt3o/nDYR4=; b=mrAgqFaBTDtoarALN+3pqi0rMGTpy4xTH5+iLm5Amr5NPGJODhdFOozdQUNNVEpNzu +fRNgbxS1DQIeNg6+H1DYxMNdhKBN06B0FFBO25ZUVqR7RCaHRRNWJ7yr8y6l6JJgVEb GmRjcC6Rm+vJHYlf0BpUp9ScZozpm/as7FLUVlCcPMvTo94U5UWjpy57YPVYBdVc1TKv IZTSVy9p5qS0A8gojVyBuEiR8vhs4CxHeJvi8WAAPz0V7OVkrS1JSsRBmCab96+DHk51 O1K7R2UINOIYjkfO8rZhi5URvTtRgHdvhc2/wobKczASMR41habkN6JGOiFil9OcW9iC 7gnw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.co.uk Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m10-v6si11349897pge.245.2018.05.21.10.39.19; Mon, 21 May 2018 10:39:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.co.uk Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753376AbeEURir (ORCPT + 99 others); Mon, 21 May 2018 13:38:47 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:45366 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753683AbeEURgq (ORCPT ); Mon, 21 May 2018 13:36:46 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: krisman) with ESMTPSA id 64FA42871A0 From: Gabriel Krisman Bertazi To: viro@ZenIV.linux.org.uk Cc: jra@google.com, tytso@mit.edu, olaf@sgi.com, darrick.wong@oracle.com, kernel@lists.collabora.co.uk, linux-fsdevel@vger.kernel.org, david@fromorbit.com, jack@suse.cz, linux-kernel@vger.kernel.org, Gabriel Krisman Bertazi Subject: [PATCH v2 07/15] nls: Add new interface for string comparisons Date: Mon, 21 May 2018 14:36:09 -0300 Message-Id: <20180521173617.31625-8-krisman@collabora.co.uk> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180521173617.31625-1-krisman@collabora.co.uk> References: <20180521173617.31625-1-krisman@collabora.co.uk> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The existing stricmp() interface is limited by not accepting separated length parameters for each string being compared. This is a problem for charsets doing normalization or full casefold comparison, since different sized strings can still be matched. To resolve this problem, this patch implements a new interface, allowing charsets to do the comparison, if needed. The original stricmp is left in the code, while all callers are not converted, but was rewritten the new interface. Signed-off-by: Gabriel Krisman Bertazi --- include/linux/nls.h | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/include/linux/nls.h b/include/linux/nls.h index 3766fbe6efc3..1a653b866a64 100644 --- a/include/linux/nls.h +++ b/include/linux/nls.h @@ -3,6 +3,7 @@ #define _LINUX_NLS_H #include +#include /* Unicode has changed over the years. Unicode code points no longer * fit into 16 bits; as of Unicode 5 valid code points range from 0 @@ -21,11 +22,18 @@ typedef u16 wchar_t; /* Arbitrary Unicode character */ typedef u32 unicode_t; +struct nls_table; struct nls_ops { int (*uni2char) (wchar_t uni, unsigned char *out, int boundlen); int (*char2uni) (const unsigned char *rawstring, int boundlen, wchar_t *uni); + int (*strncmp)(const struct nls_table *charset, + const unsigned char *str1, size_t len1, + const unsigned char *str2, size_t len2); + int (*strncasecmp)(const struct nls_table *charset, + const unsigned char *str1, size_t len1, + const unsigned char *str2, size_t len2); }; struct nls_table { @@ -105,10 +113,17 @@ static inline unsigned char nls_toupper(struct nls_table *t, unsigned char c) return nc ? nc : c; } -static inline int nls_strnicmp(struct nls_table *t, const unsigned char *s1, - const unsigned char *s2, int len) +static inline int nls_strncasecmp(struct nls_table *t, + const unsigned char *s1, size_t len1, + const unsigned char *s2, size_t len2) { - while (len--) { + if (t->ops->strncasecmp) + return t->ops->strncasecmp(t, s1, len1, s2, len2); + + if (len1 != len2) + return 1; + + while (len1--) { if (nls_tolower(t, *s1++) != nls_tolower(t, *s2++)) return 1; } @@ -116,6 +131,27 @@ static inline int nls_strnicmp(struct nls_table *t, const unsigned char *s1, return 0; } +static inline int nls_strncmp(struct nls_table *t, + const unsigned char *s1, size_t len1, + const unsigned char *s2, size_t len2) +{ + if (t->ops->strncmp) + return t->ops->strncmp(t, s1, len1, s2, len2); + + if (len1 != len2) + return 1; + + /* strnicmp did not return negative values. So let's keep the + * abi for now */ + return !!memcmp(s1, s2, len1); +} + +static inline int nls_strnicmp(struct nls_table *t, const unsigned char *s1, + const unsigned char *s2, int len) +{ + return nls_strncasecmp(t, s1, len, s2, len); +} + /* * nls_nullsize - return length of null character for codepage * @codepage - codepage for which to return length of NULL terminator -- 2.17.0