Branch data 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 "util/util.h"
24 : : #include "sss_utf8.h"
25 : :
26 : : #ifdef HAVE_LIBUNISTRING
27 : : void sss_utf8_free(void *ptr)
28 : : {
29 : : return free(ptr);
30 : : }
31 : : #elif HAVE_GLIB2
32 : 4 : void sss_utf8_free(void *ptr)
33 : : {
34 : 4 : return g_free(ptr);
35 : : }
36 : : #else
37 : : #error No unicode library
38 : : #endif
39 : :
40 : : #ifdef HAVE_LIBUNISTRING
41 : : uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen)
42 : : {
43 : : size_t llen;
44 : : uint8_t *lower;
45 : :
46 : : lower = u8_tolower(s, len, NULL, NULL, NULL, &llen);
47 : : if (!lower) return NULL;
48 : :
49 : : if (_nlen) *_nlen = llen;
50 : : return lower;
51 : : }
52 : : #elif HAVE_GLIB2
53 : 4 : uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen)
54 : : {
55 : : gchar *glower;
56 : : size_t nlen;
57 : : uint8_t *lower;
58 : :
59 : 4 : glower = g_utf8_strdown((const gchar *) s, len);
60 [ + - ]: 4 : if (!glower) return NULL;
61 : :
62 : : /* strlen() is safe here because g_utf8_strdown() always null-terminates */
63 : 4 : nlen = strlen(glower);
64 : :
65 : 4 : lower = g_malloc(nlen);
66 [ - + ]: 4 : if (!lower) {
67 : 0 : g_free(glower);
68 : 0 : return NULL;
69 : : }
70 : :
71 : 4 : memcpy(lower, glower, nlen);
72 : 4 : g_free(glower);
73 [ + - ]: 4 : if (_nlen) *_nlen = nlen;
74 : 4 : return (uint8_t *) lower;
75 : : }
76 : : #else
77 : : #error No unicode library
78 : : #endif
79 : :
80 : : #ifdef HAVE_LIBUNISTRING
81 : : bool sss_utf8_check(const uint8_t *s, size_t n)
82 : : {
83 : : if (u8_check(s, n) == NULL) {
84 : : return true;
85 : : }
86 : : return false;
87 : : }
88 : :
89 : : #elif HAVE_GLIB2
90 : 2 : bool sss_utf8_check(const uint8_t *s, size_t n)
91 : : {
92 : 2 : return g_utf8_validate((const gchar *)s, n, NULL);
93 : : }
94 : :
95 : : #else
96 : : #error No unicode library
97 : : #endif
98 : :
99 : : /* Returns EOK on match, ENOTUNIQ if comparison succeeds but
100 : : * does not match.
101 : : * May return other errno error codes on failure
102 : : */
103 : : #ifdef HAVE_LIBUNISTRING
104 : : errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2)
105 : : {
106 : :
107 : : /* Do a case-insensitive comparison.
108 : : * The input must be encoded in UTF8.
109 : : * We have no way of knowing the language,
110 : : * so we'll pass NULL for the language and
111 : : * hope for the best.
112 : : */
113 : : int ret;
114 : : int resultp;
115 : : size_t n1, n2;
116 : : errno = 0;
117 : :
118 : : n1 = u8_strlen(s1);
119 : : n2 = u8_strlen(s2);
120 : :
121 : : ret = u8_casecmp(s1, n1,
122 : : s2, n2,
123 : : NULL, NULL,
124 : : &resultp);
125 : : if (ret < 0) {
126 : : /* An error occurred */
127 : : return errno;
128 : : }
129 : :
130 : : if (resultp == 0) {
131 : : return EOK;
132 : : }
133 : : return ENOMATCH;
134 : : }
135 : :
136 : : #elif HAVE_GLIB2
137 : 33 : errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2)
138 : : {
139 : : gchar *gs1;
140 : : gchar *gs2;
141 : : gssize n1, n2;
142 : : gint gret;
143 : : errno_t ret;
144 : :
145 : 33 : n1 = g_utf8_strlen((const gchar *)s1, -1);
146 : 33 : n2 = g_utf8_strlen((const gchar *)s2, -1);
147 : :
148 : 33 : gs1 = g_utf8_casefold((const gchar *)s1, n1);
149 [ + - ]: 33 : if (gs1 == NULL) {
150 : : return ENOMEM;
151 : : }
152 : :
153 : 33 : gs2 = g_utf8_casefold((const gchar *)s2, n2);
154 [ + - ]: 33 : if (gs2 == NULL) {
155 : : return ENOMEM;
156 : : }
157 : :
158 : 33 : gret = g_utf8_collate(gs1, gs2);
159 [ + + ]: 33 : if (gret == 0) {
160 : : ret = EOK;
161 : : } else {
162 : 14 : ret = ENOMATCH;
163 : : }
164 : :
165 : 33 : g_free(gs1);
166 : 33 : g_free(gs2);
167 : :
168 : 33 : return ret;
169 : : }
170 : :
171 : : #else
172 : : #error No unicode library
173 : : #endif
174 : :
175 : 18 : bool sss_string_equal(bool cs, const char *s1, const char *s2)
176 : : {
177 [ + + ]: 18 : if (cs) {
178 : 16 : return strcmp(s1, s2) == 0;
179 : : }
180 : :
181 : 18 : return sss_utf8_case_eq((const uint8_t *)s1, (const uint8_t *)s2) == EOK;
182 : : }
|