• R/O
  • SSH

libctools: Commit

This library contains code that extends and simplifies different operations
for C language based programs.


Commit MetaInfo

Revisiónd8bcf99ba262e287b249b97a04d0e570588417c2 (tree)
Tiempo2022-10-05 12:15:28
AutorSergey Gusarov <laborer2008@gmai...>
CommiterSergey Gusarov

Log Message

std/string: No more strdup()/strndup(). Secure wrappers instead

Cambiar Resumen

Diferencia incremental

diff -r 3fe172f795a2 -r d8bcf99ba262 include/ctools/std/string.h
--- a/include/ctools/std/string.h Wed Oct 05 05:25:06 2022 +0300
+++ b/include/ctools/std/string.h Wed Oct 05 06:15:28 2022 +0300
@@ -6,7 +6,10 @@
66 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
77 *
88 * @section DESCRIPTION
9- *
9+ * All string functions below are prone to undefined behaviour(observed on practice with glibc)
10+ * when at least one argument is NULL.
11+ * See: https://stackoverflow.com/questions/21865041/in-c-what-exactly-happens-when-you-pass-a-null-pointer-to-strcmp
12+ * Each pointer represents string even if it NULL. NULL pointer is kind of empty string, not error
1013 */
1114
1215 #pragma once
@@ -66,26 +69,8 @@
6669 return str ? strlen(str) : 0;
6770 }
6871
69-#if defined (CT_OS_WINDOWS)
70-
71-extern CT_SHARED_API char* strndup(const char* s, size_t n) CT_NOEXCEPT;
72-
73-# if defined (CT_COMPL_BCC) && defined (CT_ARCH_X86)
74-static CT_FORCEINLINE char* strdup(const char* s) CT_NOEXCEPT
75-{
76- return strndup(s, strLenWrapper(s));
77-}
78-# else
79-# define strdup(str) _strdup(str)
80-# endif
81-#endif
82-
83-/*
84- * Both compare functions below are prone to undefined behaviour(observed on practice with glibc)
85- * when at least one argument is NULL.
86- * See: https://stackoverflow.com/questions/21865041/in-c-what-exactly-happens-when-you-pass-a-null-pointer-to-strcmp
87- * Each pointer represents string even if it NULL. NULL pointer is kind of empty string, not error
88- */
72+extern CT_SHARED_API char* strNDupWrapper(const char* str, size_t n) CT_NOEXCEPT;
73+extern CT_SHARED_API char* strDupWrapper(const char* str) CT_NOEXCEPT;
8974
9075 static CT_FORCEINLINE int strCmpWrapper(const char* s1, const char* s2) CT_NOEXCEPT
9176 {
diff -r 3fe172f795a2 -r d8bcf99ba262 src/std/string.c
--- a/src/std/string.c Wed Oct 05 05:25:06 2022 +0300
+++ b/src/std/string.c Wed Oct 05 06:15:28 2022 +0300
@@ -11,6 +11,9 @@
1111
1212 #include "ctools/std/string.h"
1313
14+#include "ctools/pointer.h"
15+
16+
1417 #if defined (CT_COMPL_SDCC)
1518
1619 #include "ctools/pointer.h"
@@ -40,7 +43,7 @@
4043
4144 // See also http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/strndup.c.htm
4245
43-char* strndup(const char* s, size_t n) CT_NOEXCEPT
46+static char* strndup(const char* s, size_t n) CT_NOEXCEPT
4447 {
4548 const size_t kLen = strLenWrapper(s);
4649 char* newString = CT_NULL;
@@ -71,3 +74,29 @@
7174 CT_END_NAMESPACE
7275
7376 #endif
77+
78+CT_BEGIN_NAMESPACE
79+
80+char* strNDupWrapper(const char* str, size_t n) CT_NOEXCEPT
81+{
82+ return str ? strndup(str, n) : CT_NULL;
83+}
84+
85+char* strDupWrapper(const char* str) CT_NOEXCEPT
86+{
87+#if defined (CT_OS_WINDOWS)
88+# if defined (CT_COMPL_BCC) && defined (CT_ARCH_X86)
89+
90+ return strNDupWrapper(str, strLenWrapper(str));
91+
92+# else
93+
94+ return str ? _strdup(str) : CT_NULL;
95+
96+# endif
97+#else
98+ return str ? strdup(str) : CT_NULL;
99+#endif
100+}
101+
102+CT_END_NAMESPACE
diff -r 3fe172f795a2 -r d8bcf99ba262 tests/src/std/test_string.c
--- a/tests/src/std/test_string.c Wed Oct 05 05:25:06 2022 +0300
+++ b/tests/src/std/test_string.c Wed Oct 05 06:15:28 2022 +0300
@@ -18,6 +18,7 @@
1818 CT_END_EXTERNAL_HEADERS
1919
2020 #include <ctools/std/string.h>
21+#include <ctools/pointer.h>
2122
2223
2324 void setUp(void)
@@ -32,15 +33,15 @@
3233 {
3334 const size_t kSize1 = 2;
3435 const size_t kSize2 = 4;
35- const char* str1 = CT_NULL;
36+ const char* strEmpty = CT_NULL;
3637 const char* str2 = "abc";
3738 const char* str3 = "1234";
3839 char* str4;
3940
40- TEST_ASSERT_EQUAL(strLenWrapper(str1), 0);
41+ TEST_ASSERT_EQUAL(strLenWrapper(strEmpty), 0);
4142 TEST_ASSERT_EQUAL(strLenWrapper(str2), 3);
4243
43- str4 = strdup(str2);
44+ str4 = strDupWrapper(str2);
4445 TEST_ASSERT_TRUE(strCmpWrapper(str2, str4) == 0);
4546 TEST_ASSERT_TRUE(strNCmpWrapper(str2, str4, strLenWrapper(str2)) == 0);
4647
@@ -49,15 +50,15 @@
4950 str4 = strerror(EINVAL);
5051 TEST_ASSERT_TRUE(strLenWrapper(str4) > 0);
5152
52- str4 = strndup(str2, kSize1);
53+ str4 = strNDupWrapper(str2, kSize1);
5354 TEST_ASSERT_TRUE(strLenWrapper(str4) == kSize1);
5455
55- str4 = strndup(str2, kSize2);
56+ str4 = strNDupWrapper(str2, kSize2);
5657 TEST_ASSERT_TRUE(strLenWrapper(str4) == strLenWrapper(str2));
5758
58- str4 = strndup(str2, strLenWrapper(str2));
59+ str4 = strNDupWrapper(str2, strLenWrapper(str2));
5960 TEST_ASSERT_TRUE(strCmpWrapper(str2, str4) == 0);
6061
61- TEST_ASSERT_TRUE(strCmpWrapper(str1, strdup(str1)) == 0);
62- TEST_ASSERT_TRUE(strCmpWrapper(str2, strdup(str2)) == 0);
62+ TEST_ASSERT_TRUE(strCmpWrapper(strEmpty, strDupWrapper(strEmpty)) == 0);
63+ TEST_ASSERT_TRUE(strCmpWrapper(str2, strDupWrapper(str2)) == 0);
6364 }
Show on old repository browser