Line data Source code
1 : /*
2 : SSSD
3 :
4 : Authors:
5 : Stephen Gallagher <sgallagh@redhat.com>
6 :
7 : Copyright (C) 2011 Red Hat
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "config.h"
24 :
25 : #ifdef HAVE_LIBUNISTRING
26 : #include <unistr.h>
27 : #include <unicase.h>
28 : #elif defined(HAVE_GLIB2)
29 : #include <glib.h>
30 : #endif
31 :
32 : #include "sss_utf8.h"
33 :
34 : #ifdef HAVE_LIBUNISTRING
35 : void sss_utf8_free(void *ptr)
36 : {
37 : return free(ptr);
38 : }
39 : #elif defined(HAVE_GLIB2)
40 91 : void sss_utf8_free(void *ptr)
41 : {
42 91 : return g_free(ptr);
43 : }
44 : #else
45 : #error No unicode library
46 : #endif
47 :
48 : #ifdef HAVE_LIBUNISTRING
49 : uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen)
50 : {
51 : size_t llen;
52 : uint8_t *lower;
53 :
54 : lower = u8_tolower(s, len, NULL, NULL, NULL, &llen);
55 : if (!lower) return NULL;
56 :
57 : if (_nlen) *_nlen = llen;
58 : return lower;
59 : }
60 : #elif defined(HAVE_GLIB2)
61 91 : uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen)
62 : {
63 : gchar *glower;
64 : size_t nlen;
65 : uint8_t *lower;
66 :
67 91 : glower = g_utf8_strdown((const gchar *) s, len);
68 91 : if (!glower) return NULL;
69 :
70 : /* strlen() is safe here because g_utf8_strdown() always null-terminates */
71 91 : nlen = strlen(glower);
72 :
73 91 : lower = g_malloc(nlen);
74 91 : if (!lower) {
75 0 : g_free(glower);
76 0 : return NULL;
77 : }
78 :
79 91 : memcpy(lower, glower, nlen);
80 91 : g_free(glower);
81 91 : if (_nlen) *_nlen = nlen;
82 91 : return (uint8_t *) lower;
83 : }
84 : #else
85 : #error No unicode library
86 : #endif
87 :
88 : #ifdef HAVE_LIBUNISTRING
89 : bool sss_utf8_check(const uint8_t *s, size_t n)
90 : {
91 : if (u8_check(s, n) == NULL) {
92 : return true;
93 : }
94 : return false;
95 : }
96 :
97 : #elif defined(HAVE_GLIB2)
98 226 : bool sss_utf8_check(const uint8_t *s, size_t n)
99 : {
100 226 : return g_utf8_validate((const gchar *)s, n, NULL);
101 : }
102 :
103 : #else
104 : #error No unicode library
105 : #endif
106 :
107 : /* Returns EOK on match, ENOTUNIQ if comparison succeeds but
108 : * does not match.
109 : * May return other errno error codes on failure
110 : */
111 : #ifdef HAVE_LIBUNISTRING
112 : errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2)
113 : {
114 :
115 : /* Do a case-insensitive comparison.
116 : * The input must be encoded in UTF8.
117 : * We have no way of knowing the language,
118 : * so we'll pass NULL for the language and
119 : * hope for the best.
120 : */
121 : int ret;
122 : int resultp;
123 : size_t n1, n2;
124 : errno = 0;
125 :
126 : n1 = u8_strlen(s1);
127 : n2 = u8_strlen(s2);
128 :
129 : ret = u8_casecmp(s1, n1,
130 : s2, n2,
131 : NULL, NULL,
132 : &resultp);
133 : if (ret < 0) {
134 : /* An error occurred */
135 : return errno;
136 : }
137 :
138 : if (resultp == 0) {
139 : return EOK;
140 : }
141 : return ENOMATCH;
142 : }
143 :
144 : #elif defined(HAVE_GLIB2)
145 53 : errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2)
146 : {
147 : gchar *gs1;
148 : gchar *gs2;
149 : gssize n1, n2;
150 : gint gret;
151 : errno_t ret;
152 :
153 53 : n1 = g_utf8_strlen((const gchar *)s1, -1);
154 53 : n2 = g_utf8_strlen((const gchar *)s2, -1);
155 :
156 53 : gs1 = g_utf8_casefold((const gchar *)s1, n1);
157 53 : if (gs1 == NULL) {
158 0 : return ENOMEM;
159 : }
160 :
161 53 : gs2 = g_utf8_casefold((const gchar *)s2, n2);
162 53 : if (gs2 == NULL) {
163 0 : return ENOMEM;
164 : }
165 :
166 53 : gret = g_utf8_collate(gs1, gs2);
167 53 : if (gret == 0) {
168 39 : ret = EOK;
169 : } else {
170 14 : ret = ENOMATCH;
171 : }
172 :
173 53 : g_free(gs1);
174 53 : g_free(gs2);
175 :
176 53 : return ret;
177 : }
178 :
179 : #else
180 : #error No unicode library
181 : #endif
182 :
183 40 : bool sss_string_equal(bool cs, const char *s1, const char *s2)
184 : {
185 40 : if (cs) {
186 38 : return strcmp(s1, s2) == 0;
187 : }
188 :
189 2 : return sss_utf8_case_eq((const uint8_t *)s1, (const uint8_t *)s2) == EOK;
190 : }
|