Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- For https://bugs.winehq.org/show_bug.cgi?id=43300
include/msvcrt/wchar.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h index a6797246af..a51deb14f9 100644 --- a/include/msvcrt/wchar.h +++ b/include/msvcrt/wchar.h @@ -476,6 +476,14 @@ size_t __cdecl wcrtomb(char*,wchar_t,mbstate_t*); size_t __cdecl wcsrtombs(char*,const wchar_t**,size_t,mbstate_t*); int __cdecl wctob(wint_t);
+static inline wchar_t* __cdecl wmemchr(const wchar_t *s, wchar_t c, size_t n) +{ + const wchar_t *end; + for (end = s + n; s < end; s++) + if (*s == c) return (wchar_t*)s; + return NULL; +} + #ifdef __cplusplus } #endif
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- For https://bugs.winehq.org/show_bug.cgi?id=43300
include/msvcrt/wchar.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h index a51deb14f9..6fe6f11828 100644 --- a/include/msvcrt/wchar.h +++ b/include/msvcrt/wchar.h @@ -484,6 +484,17 @@ static inline wchar_t* __cdecl wmemchr(const wchar_t *s, wchar_t c, size_t n) return NULL; }
+static inline int __cdecl wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + { + if (s1[i] > s2[i]) return 1; + if (s1[i] < s2[i]) return -1; + } + return 0; +} + #ifdef __cplusplus } #endif
Signed-off-by: Piotr Caban piotr@codeweavers.com
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- For https://bugs.winehq.org/show_bug.cgi?id=43300
include/msvcrt/wchar.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h index 6fe6f11828..a91d0f3093 100644 --- a/include/msvcrt/wchar.h +++ b/include/msvcrt/wchar.h @@ -495,6 +495,14 @@ static inline int __cdecl wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n return 0; }
+static inline wchar_t* __cdecl wmemcpy(wchar_t *dst, const wchar_t *src, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + dst[i] = src[i]; + return dst; +} + #ifdef __cplusplus } #endif
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- For https://bugs.winehq.org/show_bug.cgi?id=43300
include/msvcrt/wchar.h | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h index a91d0f3093..a92bac61fc 100644 --- a/include/msvcrt/wchar.h +++ b/include/msvcrt/wchar.h @@ -503,6 +503,15 @@ static inline wchar_t* __cdecl wmemcpy(wchar_t *dst, const wchar_t *src, size_t return dst; }
+static inline wchar_t* __cdecl wmemmove(wchar_t *dst, const wchar_t *src, size_t n) +{ + size_t i; + if (dst <= src) return wmemcpy(dst, src, n); + for (i = 1; i <= n; i++) + dst[n - i] = src[n - i]; + return dst; +} + #ifdef __cplusplus } #endif
Alex Henrie alexhenrie24@gmail.com wrote:
+static inline wchar_t* __cdecl wmemmove(wchar_t *dst, const wchar_t *src, size_t n) +{
- size_t i;
- if (dst <= src) return wmemcpy(dst, src, n);
- for (i = 1; i <= n; i++)
dst[n - i] = src[n - i];
- return dst;
+}
The optimization with wmemcpy() looks arbitrary and not safe. Why not simply call memmove(dst, src, n * sizeof(wchar_t)) ?
Shouldn't wmemcpy() implementation also simply call memcpy() in a similar way?
On Sun, May 27, 2018 at 9:20 PM Dmitry Timoshkov dmitry@baikal.ru wrote:
Alex Henrie alexhenrie24@gmail.com wrote:
+static inline wchar_t* __cdecl wmemmove(wchar_t *dst, const wchar_t
*src, size_t n)
+{
- size_t i;
- if (dst <= src) return wmemcpy(dst, src, n);
- for (i = 1; i <= n; i++)
dst[n - i] = src[n - i];
- return dst;
+}
The optimization with wmemcpy() looks arbitrary and not safe.
It looks perfectly safe to me. Can you give an example of valid inputs that would cause memory corruption?
Why not simply call memmove(dst, src, n * sizeof(wchar_t)) ?
Shouldn't wmemcpy() implementation also simply call memcpy() in a similar way?
I wasn't sure whether wchar.h on Windows includes string.h. I just tested it and it looks like it does, so we could call functions from string.h instead if that is preferred.
-Alex
Alex Henrie alexhenrie24@gmail.com wrote:
+static inline wchar_t* __cdecl wmemmove(wchar_t *dst, const wchar_t
*src, size_t n)
+{
- size_t i;
- if (dst <= src) return wmemcpy(dst, src, n);
- for (i = 1; i <= n; i++)
dst[n - i] = src[n - i];
- return dst;
+}
The optimization with wmemcpy() looks arbitrary and not safe.
It looks perfectly safe to me. Can you give an example of valid inputs that would cause memory corruption?
When the buffers overlap each other with 1 byte offset.
On 05/27/2018 09:17 PM, Alex Henrie wrote:
On Sun, May 27, 2018 at 9:20 PM Dmitry Timoshkov dmitry@baikal.ru wrote:
Alex Henrie alexhenrie24@gmail.com wrote:
+static inline wchar_t* __cdecl wmemmove(wchar_t *dst, const wchar_t
*src, size_t n)
+{
- size_t i;
- if (dst <= src) return wmemcpy(dst, src, n);
- for (i = 1; i <= n; i++)
dst[n - i] = src[n - i];
- return dst;
+}
The optimization with wmemcpy() looks arbitrary and not safe.
It looks perfectly safe to me. Can you give an example of valid inputs that would cause memory corruption?
Is there any guarantee about how pointers relate to each other? Is it related to the pointer's bit pattern interpreted as some integer type, or as if the pointers were casted/converted to some integer type? And is it a signed or unsigned comparison?
Also, checking dst <= src, even with the expected results, doesn't guarantee the two memory ranges don't overlap. Aside from when dst==src, if dst = src - i and n > i, the tail of dst would overlap the head of src.
On 28 May 2018 at 06:37, Chris Robinson chris.kcat@gmail.com wrote:
Also, checking dst <= src, even with the expected results, doesn't guarantee the two memory ranges don't overlap. Aside from when dst==src, if dst = src
- i and n > i, the tail of dst would overlap the head of src.
I'd also rather see this implemented on top of memmove(), but for what it's worth, the wmemcpy() implementation in the preceding patch is sufficiently naive that that kind of overlap shouldn't be an issue.
On 05/28/18 06:17, Alex Henrie wrote:
On Sun, May 27, 2018 at 9:20 PM Dmitry Timoshkov dmitry@baikal.ru wrote:
Shouldn't wmemcpy() implementation also simply call memcpy() in a similar way?
I wasn't sure whether wchar.h on Windows includes string.h. I just tested it and it looks like it does, so we could call functions from string.h instead if that is preferred.
Yes, I think it's preferred to call memcpy / memmove.
Thanks, Piotr
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- For https://bugs.winehq.org/show_bug.cgi?id=43300
include/msvcrt/wchar.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h index a92bac61fc..448352cd2a 100644 --- a/include/msvcrt/wchar.h +++ b/include/msvcrt/wchar.h @@ -512,6 +512,14 @@ static inline wchar_t* __cdecl wmemmove(wchar_t *dst, const wchar_t *src, size_t return dst; }
+static inline wchar_t* __cdecl wmemset(wchar_t *s, wchar_t c, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + s[i] = c; + return s; +} + #ifdef __cplusplus } #endif