summaryrefslogtreecommitdiff
path: root/src/util/win32/utf-conv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/win32/utf-conv.c')
-rw-r--r--src/util/win32/utf-conv.c148
1 files changed, 73 insertions, 75 deletions
diff --git a/src/util/win32/utf-conv.c b/src/util/win32/utf-conv.c
index 4bde3023a..ad35c0c35 100644
--- a/src/util/win32/utf-conv.c
+++ b/src/util/win32/utf-conv.c
@@ -15,108 +15,114 @@ GIT_INLINE(void) git__set_errno(void)
errno = EINVAL;
}
-/**
- * Converts a UTF-8 string to wide characters.
- *
- * @param dest The buffer to receive the wide string.
- * @param dest_size The size of the buffer, in characters.
- * @param src The UTF-8 string to convert.
- * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
- */
-int git__utf8_to_16(wchar_t *dest, size_t dest_size, const char *src)
+int git_utf8_to_16(wchar_t *dest, size_t dest_size, const char *src)
+{
+ /* Length of -1 indicates NULL termination of the input string. */
+ return git_utf8_to_16_with_len(dest, dest_size, src, -1);
+}
+
+int git_utf8_to_16_with_len(
+ wchar_t *dest,
+ size_t _dest_size,
+ const char *src,
+ int src_len)
{
+ int dest_size = (int)min(_dest_size, INT_MAX);
int len;
- /* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
- * turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
- * length. MultiByteToWideChar never returns int's minvalue, so underflow is not possible */
- if ((len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, dest, (int)dest_size) - 1) < 0)
+ /*
+ * Subtract 1 from the result to turn 0 into -1 (an error code) and
+ * to not count the NULL terminator as part of the string's length.
+ * MultiByteToWideChar never returns int's minvalue, so underflow
+ * is not possible.
+ */
+ len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+ src, src_len, dest, dest_size) - 1;
+
+ if (len < 0)
git__set_errno();
return len;
}
-/**
- * Converts a wide string to UTF-8.
- *
- * @param dest The buffer to receive the UTF-8 string.
- * @param dest_size The size of the buffer, in bytes.
- * @param src The wide string to convert.
- * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
- */
-int git__utf16_to_8(char *dest, size_t dest_size, const wchar_t *src)
+int git_utf8_from_16(char *dest, size_t dest_size, const wchar_t *src)
{
+ /* Length of -1 indicates NULL termination of the input string. */
+ return git_utf8_from_16_with_len(dest, dest_size, src, -1);
+}
+
+int git_utf8_from_16_with_len(
+ char *dest,
+ size_t _dest_size,
+ const wchar_t *src,
+ int src_len)
+{
+ int dest_size = (int)min(_dest_size, INT_MAX);
int len;
- /* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
- * turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
- * length. WideCharToMultiByte never returns int's minvalue, so underflow is not possible */
- if ((len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, dest, (int)dest_size, NULL, NULL) - 1) < 0)
+ /*
+ * Subtract 1 from the result to turn 0 into -1 (an error code) and
+ * to not count the NULL terminator as part of the string's length.
+ * WideCharToMultiByte never returns int's minvalue, so underflow
+ * is not possible.
+ */
+ len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
+ src, src_len, dest, dest_size, NULL, NULL) - 1;
+
+ if (len < 0)
git__set_errno();
return len;
}
-/**
- * Converts a UTF-8 string to wide characters.
- * Memory is allocated to hold the converted string.
- * The caller is responsible for freeing the string with git__free.
- *
- * @param dest Receives a pointer to the wide string.
- * @param src The UTF-8 string to convert.
- * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
- */
-int git__utf8_to_16_alloc(wchar_t **dest, const char *src)
+int git_utf8_to_16_alloc(wchar_t **dest, const char *src)
+{
+ /* Length of -1 indicates NULL termination of the input string. */
+ return git_utf8_to_16_alloc_with_len(dest, src, -1);
+}
+
+int git_utf8_to_16_alloc_with_len(wchar_t **dest, const char *src, int src_len)
{
int utf16_size;
*dest = NULL;
- /* Length of -1 indicates NULL termination of the input string */
- utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, NULL, 0);
+ utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+ src, src_len, NULL, 0);
if (!utf16_size) {
git__set_errno();
return -1;
}
- if (!(*dest = git__mallocarray(utf16_size, sizeof(wchar_t)))) {
- errno = ENOMEM;
- return -1;
- }
+ *dest = git__mallocarray(utf16_size, sizeof(wchar_t));
+ GIT_ERROR_CHECK_ALLOC(*dest);
- utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, *dest, utf16_size);
-
- if (!utf16_size) {
- git__set_errno();
+ utf16_size = git_utf8_to_16_with_len(*dest, (size_t)utf16_size,
+ src, src_len);
+ if (utf16_size < 0) {
git__free(*dest);
*dest = NULL;
}
- /* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
- * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
- * so underflow is not possible */
- return utf16_size - 1;
+ return utf16_size;
}
-/**
- * Converts a wide string to UTF-8.
- * Memory is allocated to hold the converted string.
- * The caller is responsible for freeing the string with git__free.
- *
- * @param dest Receives a pointer to the UTF-8 string.
- * @param src The wide string to convert.
- * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
- */
-int git__utf16_to_8_alloc(char **dest, const wchar_t *src)
+int git_utf8_from_16_alloc(char **dest, const wchar_t *src)
+{
+ /* Length of -1 indicates NULL termination of the input string. */
+ return git_utf8_from_16_alloc_with_len(dest, src, -1);
+}
+
+int git_utf8_from_16_alloc_with_len(char **dest, const wchar_t *src, int src_len)
{
int utf8_size;
*dest = NULL;
- /* Length of -1 indicates NULL termination of the input string */
- utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL);
+ utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
+ src, src_len, NULL, 0, NULL, NULL);
if (!utf8_size) {
git__set_errno();
@@ -124,23 +130,15 @@ int git__utf16_to_8_alloc(char **dest, const wchar_t *src)
}
*dest = git__malloc(utf8_size);
+ GIT_ERROR_CHECK_ALLOC(*dest);
- if (!*dest) {
- errno = ENOMEM;
- return -1;
- }
-
- utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, *dest, utf8_size, NULL, NULL);
-
- if (!utf8_size) {
- git__set_errno();
+ utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
+ src, src_len, *dest, utf8_size, NULL, NULL);
+ if (utf8_size < 0) {
git__free(*dest);
*dest = NULL;
}
- /* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
- * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
- * so underflow is not possible */
- return utf8_size - 1;
+ return utf8_size;
}