aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-01-16 19:23:00 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-01-16 19:23:00 +0000
commitad9b3c3814e92a2bb1ce1cd114328d5de741c33d (patch)
treeea1f1433119ed0d6c39df0233847f67519deca3b
parent56810e175c26cb40f8b7df2fdcf7a7defd6bbabe (diff)
downloadlibmicrohttpd-ad9b3c3814e92a2bb1ce1cd114328d5de741c33d.tar.gz
libmicrohttpd-ad9b3c3814e92a2bb1ce1cd114328d5de741c33d.zip
Use only US-ASCII charset when comparing stings as caseless as required by standard.
Comparisons for HTTP headers must not be affected by locale settings.
-rw-r--r--ChangeLog5
-rw-r--r--configure.ac54
-rw-r--r--src/include/platform_interface.h37
-rw-r--r--src/microhttpd/Makefile.am1
-rw-r--r--src/microhttpd/connection.c1
-rw-r--r--src/microhttpd/digestauth.c1
-rw-r--r--src/microhttpd/mhd_str.c231
-rw-r--r--src/microhttpd/mhd_str.h62
-rw-r--r--src/microhttpd/postprocessor.c1
-rw-r--r--w32/common/MHD_config.h10
-rw-r--r--w32/common/libmicrohttpd-files.vcxproj2
-rw-r--r--w32/common/libmicrohttpd-filters.vcxproj6
12 files changed, 374 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index ac8e0ce3..55316836 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
1Sat Jan 16 19:14:39 CET 2016
2 Use US-ASCII only (instead of user locale settings) when
3 performing caseless string comparison as required by
4 standard. -EG
5
1Tue Jan 12 16:10:09 CET 2016 6Tue Jan 12 16:10:09 CET 2016
2 Fixed declaraion of MHD_get_reason_phrase_for(). -EG 7 Fixed declaraion of MHD_get_reason_phrase_for(). -EG
3 8
diff --git a/configure.ac b/configure.ac
index a2d522a5..ba798e0c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -86,6 +86,60 @@ MHD_LIBDEPS=""
86MHD_REQ_PRIVATE='' 86MHD_REQ_PRIVATE=''
87MHD_LIBDEPS_PKGCFG='' 87MHD_LIBDEPS_PKGCFG=''
88 88
89AC_CHECK_TYPE([_Bool],
90 [ AC_DEFINE([_MHD_bool],[_Bool],[Define to type which will be used as boolean type.]) ],
91 [
92 AC_CHECK_HEADER([stdbool.h], [ AC_DEFINE([HAVE_STDBOOL_H],[1],[Define to 1 if you have the <stdbool.h> header file and it's required for _MHD_bool.]) ])
93 AC_CHECK_TYPE([bool],
94 [ AC_DEFINE([_MHD_bool],[bool]) ],
95 [ AC_DEFINE([_MHD_bool],[int]) ],
96 [[
97 #ifdef HAVE_STDBOOL_H
98 #include <stdbool.h>
99 #endif
100 ]])
101 ])
102
103AC_MSG_CHECKING([[for function inline keywords suppoted by $CC]])
104save_CFLAGS="$CFLAGS"
105AX_APPEND_FLAG([[-Werror=attributes]])
106inln_prfx="none"
107# Prefer always inline functions
108for inln_prfx_chk in "inline __attribute__((always_inline))" __forceinline inline __inline__ __inline _inline _Inline; do
109 # Try to link to avoid "symbol undefined" problems at build time
110 AC_LINK_IFELSE(
111 [
112 AC_LANG_PROGRAM(
113 [[
114 #ifdef __cplusplus
115 choke me
116 #endif
117 #ifdef HAVE_STDBOOL_H
118 #include <stdbool.h>
119 #endif
120 static $inln_prfx_chk _MHD_bool cmpfn(int x, int y)
121 { return x > y; }
122 static $inln_prfx_chk int sumfn(int x, int y)
123 { return x + y; }
124 ]],[[
125 int a = 1, b = 100, c;
126 if (cmpfn(a, b))
127 c = sumfn(a, b);
128 else
129 c = 0 - sumfn(a, b);
130 ]])
131 ],
132 [[ inln_prfx="$inln_prfx_chk" ]])
133 test "x$inln_prfx" != "xnone" && break
134done
135AS_IF([[test "x$ac_cv_c_inline" != "xnone"]],
136 [
137 AC_DEFINE([INLINE_FUNC],[1],[Define to 1 if your C compiler supports inline functions.])
138 AC_DEFINE_UNQUOTED([_MHD_inline],[static $inln_prfx],[Define to prefix which will be used with MHD inline functions.])
139 ])
140AC_MSG_RESULT([[$inln_prfx]])
141CFLAGS="$save_CFLAGS"
142
89# Check system type 143# Check system type
90AC_MSG_CHECKING([[for target host OS]]) 144AC_MSG_CHECKING([[for target host OS]])
91case "$host_os" in 145case "$host_os" in
diff --git a/src/include/platform_interface.h b/src/include/platform_interface.h
index 48a7e6f7..b5623c38 100644
--- a/src/include/platform_interface.h
+++ b/src/include/platform_interface.h
@@ -34,43 +34,6 @@
34/* ***************************** 34/* *****************************
35 General function mapping 35 General function mapping
36 *****************************/ 36 *****************************/
37#if !defined(_WIN32) || defined(__CYGWIN__)
38/**
39 * Check two strings case-insensitive equality
40 * @param a first string to check
41 * @param b second string to check
42 * @return boolean true if strings are equal, boolean false if strings are unequal
43 */
44#define MHD_str_equal_caseless_(a,b) (0==strcasecmp((a),(b)))
45#else
46/**
47 * Check two strings case-insensitive equality
48 * @param a first string to check
49 * @param b second string to check
50 * @return boolean true if strings are equal, boolean false if strings are unequal
51 */
52#define MHD_str_equal_caseless_(a,b) (0==_stricmp((a),(b)))
53#endif
54
55#if !defined(_WIN32) || defined(__CYGWIN__)
56/**
57 * Check not more than n chars in two strings case-insensitive equality
58 * @param a first string to check
59 * @param b second string to check
60 * @param n maximum number of chars to check
61 * @return boolean true if strings are equal, boolean false if strings are unequal
62 */
63#define MHD_str_equal_caseless_n_(a,b,n) (0==strncasecmp((a),(b),(n)))
64#else
65/**
66 * Check not more than n chars in two strings case-insensitive equality
67 * @param a first string to check
68 * @param b second string to check
69 * @param n maximum number of chars to check
70 * @return boolean true if strings are equal, boolean false if strings are unequal
71 */
72#define MHD_str_equal_caseless_n_(a,b,n) (0==_strnicmp((a),(b),(n)))
73#endif
74 37
75/* Platform-independent snprintf name */ 38/* Platform-independent snprintf name */
76#if defined(HAVE_SNPRINTF) 39#if defined(HAVE_SNPRINTF)
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index b22560c3..9b7bc471 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -65,6 +65,7 @@ libmicrohttpd_la_SOURCES = \
65 mhd_mono_clock.c mhd_mono_clock.h \ 65 mhd_mono_clock.c mhd_mono_clock.h \
66 mhd_limits.h mhd_byteorder.h \ 66 mhd_limits.h mhd_byteorder.h \
67 sysfdsetsize.c sysfdsetsize.h \ 67 sysfdsetsize.c sysfdsetsize.h \
68 mhd_str.c mhd_str.h \
68 response.c response.h 69 response.c response.h
69libmicrohttpd_la_CPPFLAGS = \ 70libmicrohttpd_la_CPPFLAGS = \
70 $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) \ 71 $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) \
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 30aac8c7..e3f92567 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -30,6 +30,7 @@
30#include "memorypool.h" 30#include "memorypool.h"
31#include "response.h" 31#include "response.h"
32#include "mhd_mono_clock.h" 32#include "mhd_mono_clock.h"
33#include "mhd_str.h"
33 34
34#if HAVE_NETINET_TCP_H 35#if HAVE_NETINET_TCP_H
35/* for TCP_CORK */ 36/* for TCP_CORK */
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index 992328c5..6984fc2e 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -27,6 +27,7 @@
27#include "internal.h" 27#include "internal.h"
28#include "md5.h" 28#include "md5.h"
29#include "mhd_mono_clock.h" 29#include "mhd_mono_clock.h"
30#include "mhd_str.h"
30 31
31#if defined(_WIN32) && defined(MHD_W32_MUTEX_) 32#if defined(_WIN32) && defined(MHD_W32_MUTEX_)
32#ifndef WIN32_LEAN_AND_MEAN 33#ifndef WIN32_LEAN_AND_MEAN
diff --git a/src/microhttpd/mhd_str.c b/src/microhttpd/mhd_str.c
new file mode 100644
index 00000000..1e9154ba
--- /dev/null
+++ b/src/microhttpd/mhd_str.c
@@ -0,0 +1,231 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2015 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file microhttpd/mhd_str.c
22 * @brief Functions implementations for string manipulating
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "mhd_str.h"
27
28#include "MHD_config.h"
29
30#ifdef HAVE_STDBOOL_H
31#include <stdbool.h>
32#endif
33
34/*
35 * Block of functions/macros that use US-ASCII charset as required by HTTP
36 * standards. Not affected by current locale settings.
37 */
38
39#ifdef INLINE_FUNC
40 /**
41 * Check whether character is lower case letter in US-ASCII
42 * @param c character to check
43 * @return non-zero if character is lower case letter, zero otherwise
44 */
45_MHD_inline _MHD_bool
46isasciilower (char c)
47{
48 return c >= 'a' && c <= 'z';
49}
50
51/**
52 * Check whether character is upper case letter in US-ASCII
53 * @param c character to check
54 * @return non-zero if character is upper case letter, zero otherwise
55 */
56_MHD_inline _MHD_bool
57isasciiupper (char c)
58{
59 return c >= 'A' && c <= 'Z';
60}
61
62/**
63 * Check whether character is letter in US-ASCII
64 * @param c character to check
65 * @return non-zero if character is letter in US-ASCII, zero otherwise
66 */
67_MHD_inline _MHD_bool
68isasciialpha (char c)
69{
70 return isasciilower (c) || isasciiupper (c);
71}
72
73/**
74 * Check whether character is decimal digit in US-ASCII
75 * @param c character to check
76 * @return non-zero if character is decimal digit, zero otherwise
77 */
78_MHD_inline _MHD_bool
79isasciidigit (char c)
80{
81 return c >= '0' && c <= '9';
82}
83
84/**
85 * Check whether character is decimal digit or letter in US-ASCII
86 * @param c character to check
87 * @return non-zero if character is decimal digit or letter, zero otherwise
88 */
89_MHD_inline _MHD_bool
90isasciialmun (char c)
91{
92 return isasciialpha (c) || isasciidigit (c);
93}
94
95/**
96 * Convert US-ASCII character to lower case.
97 * If character is upper case letter in US-ASCII than it's converted to lower
98 * case analog. If character is NOT upper case letter than it's returned
99 * unmodified.
100 * @param c character to check
101 * @return converted to lower case character
102 */
103_MHD_inline char
104toasciilower (char c)
105{
106 return isasciiupper (c) ? (c - 'A' + 'a') : c;
107}
108
109 /**
110 * Convert US-ASCII character to upper case.
111 * If character is lower case letter in US-ASCII than it's converted to upper
112 * case analog. If character is NOT lower case letter than it's returned
113 * unmodified.
114 * @param c character to check
115 * @return converted to upper case character
116 */
117_MHD_inline char
118toasciiupper (char c)
119{
120 return isasciilower (c) ? (c - 'a' + 'A') : c;
121}
122
123#else /* !INLINE_FUNC */
124
125/**
126 * Checks whether character is lower case letter in US-ASCII
127 * @param c character to check
128 * @return boolean true if character is lower case letter,
129 * boolean false otherwise
130 */
131#define isasciilower(c) (((char)(c)) >= 'a' && ((char)(c)) <= 'z')
132
133/**
134 * Checks whether character is upper case letter in US-ASCII
135 * @param c character to check
136 * @return boolean true if character is upper case letter,
137 * boolean false otherwise
138 */
139#define isasciiupper(c) (((char)(c)) >= 'A' && ((char)(c)) <= 'Z')
140
141/**
142 * Checks whether character is letter in US-ASCII
143 * @param c character to check
144 * @return boolean true if character is letter, boolean false
145 * otherwise
146 */
147#define isasciialpha(c) (isasciilower(c) || isasciiupper(c))
148
149/**
150 * Check whether character is decimal digit in US-ASCII
151 * @param c character to check
152 * @return boolean true if character is decimal digit, boolean false
153 * otherwise
154 */
155#define isasciidigit(c) (((char)(c)) >= '0' && ((char)(c)) <= '9')
156
157 /**
158 * Check whether character is decimal digit or letter in US-ASCII
159 * @param c character to check
160 * @return boolean true if character is decimal digit or letter,
161 * boolean false otherwise
162 */
163#define isasciialmun(c) (isasciialpha(c) || isasciidigit(c))
164
165/**
166 * Convert US-ASCII character to lower case.
167 * If character is upper case letter in US-ASCII than it's converted to lower
168 * case analog. If character is NOT upper case letter than it's returned
169 * unmodified.
170 * @param c character to check
171 * @return converted to lower case character
172 */
173#define toasciilower(c) ((isasciiupper(c)) ? (((char)(c)) - 'A' + 'a') : ((char)(c)))
174
175/**
176 * Convert US-ASCII character to upper case.
177 * If character is lower case letter in US-ASCII than it's converted to upper
178 * case analog. If character is NOT lower case letter than it's returned
179 * unmodified.
180 * @param c character to check
181 * @return converted to upper case character
182 */
183#define toasciiupper(c) ((isasciilower(c)) ? (((char)(c)) - 'a' + 'A') : ((char)(c)))
184#endif /* !INLINE_FUNC */
185
186/**
187 * Check two string for equality, ignoring case of US-ASCII letters.
188 * @param str1 first string to compare
189 * @param str2 second string to compare
190 * @return non-zero if two strings are equal, zero otherwise.
191 */
192int
193MHD_str_equal_caseless_ (const char * str1, const char * str2)
194{
195 while (0 != (*str1))
196 {
197 const char c1 = *str1;
198 const char c2 = *str2;
199 if (c1 != c2 && toasciilower (c1) != toasciilower (c2))
200 return 0;
201 str1++;
202 str2++;
203 }
204 return 0 == (*str2);
205}
206
207
208/**
209 * Check two string for equality, ignoring case of US-ASCII letters and
210 * checking not more than @a maxlen characters.
211 * Compares up to first terminating null character, but not more than
212 * first @a maxlen characters.
213 * @param str1 first string to compare
214 * @param str2 second string to compare
215 * @patam maxlen maximum number of characters to compare
216 * @return non-zero if two strings are equal, zero otherwise.
217 */
218int
219MHD_str_equal_caseless_n_ (const char * const str1, const char * const str2, size_t maxlen)
220{
221 for (size_t i = 0; i < maxlen; ++i)
222 {
223 const char c1 = str1[i];
224 const char c2 = str2[i];
225 if (0 == c2)
226 return 0 == c1;
227 if (c1 != c2 && toasciilower (c1) != toasciilower (c2))
228 return 0;
229 }
230 return !0;
231}
diff --git a/src/microhttpd/mhd_str.h b/src/microhttpd/mhd_str.h
new file mode 100644
index 00000000..59902e80
--- /dev/null
+++ b/src/microhttpd/mhd_str.h
@@ -0,0 +1,62 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2015 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file microhttpd/mhd_str.h
22 * @brief Header for string manipulating helpers
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#ifndef MHD_STR_H
27#define MHD_STR_H 1
28
29#include <stdint.h>
30
31/*
32 * Block of functions/macros that use US-ASCII charset as required by HTTP
33 * standards. Not affected by current locale settings.
34 */
35
36/**
37 * Check two string for equality, ignoring case of US-ASCII letters.
38 * @param str1 first string to compare
39 * @param str2 second string to compare
40 * @return non-zero if two strings are equal, zero otherwise.
41 */
42int
43MHD_str_equal_caseless_ (const char * str1,
44 const char * str2);
45
46
47/**
48 * Check two string for equality, ignoring case of US-ASCII letters and
49 * checking not more than @a maxlen characters.
50 * Compares up to first terminating null character, but not more than
51 * first @a maxlen characters.
52 * @param str1 first string to compare
53 * @param str2 second string to compare
54 * @patam maxlen maximum number of characters to compare
55 * @return non-zero if two strings are equal, zero otherwise.
56 */
57int
58MHD_str_equal_caseless_n_ (const char * const str1,
59 const char * const str2,
60 size_t maxlen);
61
62#endif /* MHD_STR_H */
diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c
index 8dad8ee1..c8739042 100644
--- a/src/microhttpd/postprocessor.c
+++ b/src/microhttpd/postprocessor.c
@@ -24,6 +24,7 @@
24 */ 24 */
25 25
26#include "internal.h" 26#include "internal.h"
27#include "mhd_str.h"
27 28
28/** 29/**
29 * Size of on-stack buffer that we use for un-escaping of the value. 30 * Size of on-stack buffer that we use for un-escaping of the value.
diff --git a/w32/common/MHD_config.h b/w32/common/MHD_config.h
index fd23da2c..c5b32e72 100644
--- a/w32/common/MHD_config.h
+++ b/w32/common/MHD_config.h
@@ -9,6 +9,16 @@
9/* Define if MS VC compiler is used */ 9/* Define if MS VC compiler is used */
10#define MSVC 1 10#define MSVC 1
11 11
12/* Define to type which will be used as boolean type. */
13#define _MHD_bool _Bool
14
15/* Define to 1 if your C compiler supports inline functions. */
16#define INLINE_FUNC 1
17
18/* Define to prefix which will be used with MHD inline functions. */
19#define _MHD_inline static __forceinline
20
21
12/* *** MHD configuration *** */ 22/* *** MHD configuration *** */
13/* Undef to disable feature */ 23/* Undef to disable feature */
14 24
diff --git a/w32/common/libmicrohttpd-files.vcxproj b/w32/common/libmicrohttpd-files.vcxproj
index bf074ae3..7c451823 100644
--- a/w32/common/libmicrohttpd-files.vcxproj
+++ b/w32/common/libmicrohttpd-files.vcxproj
@@ -15,6 +15,7 @@
15 <ClCompile Include="$(MhdSrc)microhttpd\response.c" /> 15 <ClCompile Include="$(MhdSrc)microhttpd\response.c" />
16 <ClCompile Include="$(MhdSrc)microhttpd\tsearch.c" /> 16 <ClCompile Include="$(MhdSrc)microhttpd\tsearch.c" />
17 <ClCompile Include="$(MhdSrc)microhttpd\sysfdsetsize.c" /> 17 <ClCompile Include="$(MhdSrc)microhttpd\sysfdsetsize.c" />
18 <ClCompile Include="$(MhdSrc)microhttpd\mhd_str.c" />
18 <ClCompile Include="$(MhdSrc)platform\w32functions.c" /> 19 <ClCompile Include="$(MhdSrc)platform\w32functions.c" />
19 </ItemGroup> 20 </ItemGroup>
20 <ItemGroup> 21 <ItemGroup>
@@ -34,6 +35,7 @@
34 <ClInclude Include="$(MhdSrc)microhttpd\response.h" /> 35 <ClInclude Include="$(MhdSrc)microhttpd\response.h" />
35 <ClInclude Include="$(MhdSrc)microhttpd\tsearch.h" /> 36 <ClInclude Include="$(MhdSrc)microhttpd\tsearch.h" />
36 <ClInclude Include="$(MhdSrc)microhttpd\sysfdsetsize.h" /> 37 <ClInclude Include="$(MhdSrc)microhttpd\sysfdsetsize.h" />
38 <ClInclude Include="$(MhdSrc)microhttpd\mhd_str.h" />
37 <ClInclude Include="$(MhdW32Common)MHD_config.h" /> 39 <ClInclude Include="$(MhdW32Common)MHD_config.h" />
38 </ItemGroup> 40 </ItemGroup>
39 <ItemGroup> 41 <ItemGroup>
diff --git a/w32/common/libmicrohttpd-filters.vcxproj b/w32/common/libmicrohttpd-filters.vcxproj
index 36816216..27ee4804 100644
--- a/w32/common/libmicrohttpd-filters.vcxproj
+++ b/w32/common/libmicrohttpd-filters.vcxproj
@@ -121,6 +121,12 @@
121 <ClCompile Include="$(MhdSrc)microhttpd\sysfdsetsize.c"> 121 <ClCompile Include="$(MhdSrc)microhttpd\sysfdsetsize.c">
122 <Filter>Source Files</Filter> 122 <Filter>Source Files</Filter>
123 </ClCompile> 123 </ClCompile>
124 <ClInclude Include="$(MhdSrc)microhttpd\mhd_str.h">
125 <Filter>Source Files</Filter>
126 </ClInclude>
127 <ClCompile Include="$(MhdSrc)microhttpd\mhd_str.c">
128 <Filter>Source Files</Filter>
129 </ClCompile>
124 </ItemGroup> 130 </ItemGroup>
125 <ItemGroup> 131 <ItemGroup>
126 <ResourceCompile Include="$(MhdW32Common)microhttpd_dll_res_vc.rc"> 132 <ResourceCompile Include="$(MhdW32Common)microhttpd_dll_res_vc.rc">