浏览代码

Add dst_size parameter to character conv funcs

Character conversion functions did not previously ask for a maximum
buffer size for their 'dst' parameter, it's unsafe to assume some given
destination buffer may have enough size to accommodate a conversion.
jp9000 11 年之前
父节点
当前提交
d536df30b0
共有 5 个文件被更改,包括 81 次插入35 次删除
  1. 3 1
      libobs/util/platform-windows.c
  2. 59 20
      libobs/util/platform.c
  3. 8 4
      libobs/util/platform.h
  4. 1 1
      obs/platform-windows.cpp
  5. 10 9
      plugins/win-wasapi/enum-wasapi.cpp

+ 3 - 1
libobs/util/platform-windows.c

@@ -214,7 +214,9 @@ struct os_dirent *os_readdir(os_dir_t dir)
 			return NULL;
 	}
 
-	os_wcs_to_utf8(dir->wfd.cFileName, 255, dir->out.d_name);
+	os_wcs_to_utf8(dir->wfd.cFileName, 0, dir->out.d_name,
+			sizeof(dir->out.d_name));
+
 	dir->out.directory =
 		!!(dir->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
 

+ 59 - 20
libobs/util/platform.c

@@ -228,50 +228,88 @@ bool os_quick_write_utf8_file(const char *path, const char *str, size_t len,
 	return true;
 }
 
-size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst)
+size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst, size_t dst_size)
 {
 	size_t out_len = dst ? len : mbstowcs(NULL, str, len);
 
 	if (len && dst) {
-		mbstowcs(dst, str, out_len+1);
+		if (!dst_size)
+			return 0;
+
+		if (out_len) {
+			if ((out_len + 1) > dst_size)
+				out_len = dst_size - 1;
+
+			mbstowcs(dst, str, out_len + 1);
+		}
+
 		dst[out_len] = 0;
 	}
 
 	return out_len;
 }
 
-size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst)
+size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst,
+		size_t dst_size)
 {
 	size_t in_len = len ? len : strlen(str);
 	size_t out_len = dst ? len : utf8_to_wchar(str, in_len, NULL, 0, 0);
 
 	if (out_len && dst) {
-		utf8_to_wchar(str, in_len, dst, out_len+1, 0);
+		if (!dst_size)
+			return 0;
+
+		if (out_len) {
+			if ((out_len + 1) > dst_size)
+				out_len = dst_size - 1;
+
+			utf8_to_wchar(str, in_len, dst, out_len + 1, 0);
+		}
+
 		dst[out_len] = 0;
 	}
 
 	return out_len;
 }
 
-size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst)
+size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst, size_t dst_size)
 {
 	size_t out_len = dst ? len : wcstombs(NULL, str, len);
 
 	if (len && dst) {
-		wcstombs(dst, str, out_len+1);
+		if (!dst_size)
+			return 0;
+
+		if (out_len) {
+			if ((out_len + 1) > dst_size)
+				out_len = dst_size - 1;
+
+			wcstombs(dst, str, out_len + 1);
+		}
+
 		dst[out_len] = 0;
 	}
 
 	return out_len;
 }
 
-size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst)
+size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst,
+		size_t dst_size)
 {
 	size_t in_len = (len != 0) ? len : wcslen(str);
 	size_t out_len = dst ? len : wchar_to_utf8(str, in_len, NULL, 0, 0);
 
 	if (out_len && dst) {
-		wchar_to_utf8(str, in_len, dst, out_len+1, 0);
+		if (!dst_size)
+			return 0;
+
+		if (out_len) {
+			if ((out_len + 1) > dst_size)
+				out_len = dst_size - 1;
+
+			wchar_to_utf8(str, in_len, dst, out_len + 1, 0);
+		}
+
 		dst[out_len] = 0;
 	}
 
@@ -280,33 +318,34 @@ size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst)
 
 size_t os_mbs_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr)
 {
-	size_t  out_len = os_mbs_to_wcs(str, len, NULL);
+	size_t  out_len = os_mbs_to_wcs(str, len, NULL, 0);
 
-	*pstr = bmalloc((out_len+1) * sizeof(wchar_t));
-	return os_mbs_to_wcs(str, out_len, *pstr);
+	*pstr = bmalloc((out_len + 1) * sizeof(wchar_t));
+	return os_mbs_to_wcs(str, out_len, *pstr, out_len + 1);
 }
 
 size_t os_utf8_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr)
 {
-	size_t  out_len = os_utf8_to_wcs(str, len, NULL);
-	*pstr = bmalloc((out_len+1) * sizeof(wchar_t));
-	return os_utf8_to_wcs(str, out_len, *pstr);
+	size_t  out_len = os_utf8_to_wcs(str, len, NULL, 0);
+
+	*pstr = bmalloc((out_len + 1) * sizeof(wchar_t));
+	return os_utf8_to_wcs(str, out_len, *pstr, out_len + 1);
 }
 
 size_t os_wcs_to_mbs_ptr(const wchar_t *str, size_t len, char **pstr)
 {
-	size_t out_len = os_wcs_to_mbs(str, len, NULL);
+	size_t out_len = os_wcs_to_mbs(str, len, NULL, 0);
 
-	*pstr = bmalloc((out_len+1) * sizeof(char));
-	return os_wcs_to_mbs(str, out_len, *pstr);
+	*pstr = bmalloc((out_len + 1) * sizeof(char));
+	return os_wcs_to_mbs(str, out_len, *pstr, out_len + 1);
 }
 
 size_t os_wcs_to_utf8_ptr(const wchar_t *str, size_t len, char **pstr)
 {
-	size_t out_len = os_wcs_to_utf8(str, len, NULL);
+	size_t out_len = os_wcs_to_utf8(str, len, NULL, 0);
 
-	*pstr = bmalloc((out_len+1) * sizeof(char));
-	return os_wcs_to_utf8(str, out_len, *pstr);
+	*pstr = bmalloc((out_len + 1) * sizeof(char));
+	return os_wcs_to_utf8(str, out_len, *pstr, out_len + 1);
 }
 
 size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr)

+ 8 - 4
libobs/util/platform.h

@@ -48,10 +48,14 @@ EXPORT char *os_quick_read_mbs_file(const char *path);
 EXPORT bool os_quick_write_mbs_file(const char *path, const char *str,
 		size_t len);
 
-EXPORT size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst);
-EXPORT size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst);
-EXPORT size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst);
-EXPORT size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst);
+EXPORT size_t os_mbs_to_wcs(const char *str, size_t str_len, wchar_t *dst,
+		size_t dst_size);
+EXPORT size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst,
+		size_t dst_size);
+EXPORT size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst,
+		size_t dst_size);
+EXPORT size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst,
+		size_t dst_size);
 
 EXPORT size_t os_mbs_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr);
 EXPORT size_t os_utf8_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr);

+ 1 - 1
obs/platform-windows.cpp

@@ -78,6 +78,6 @@ string GetDefaultVideoSavePath()
 	SHGetFolderPathW(NULL, CSIDL_MYVIDEO, NULL, SHGFP_TYPE_CURRENT,
 			path_utf16);
 
-	os_wcs_to_utf8(path_utf16, wcslen(path_utf16), path_utf8);
+	os_wcs_to_utf8(path_utf16, wcslen(path_utf16), path_utf8, MAX_PATH);
 	return string(path_utf8);
 }

+ 10 - 9
plugins/win-wasapi/enum-wasapi.cpp

@@ -21,14 +21,14 @@ string GetDeviceName(IMMDevice *device)
 		res = store->GetValue(PKEY_Device_FriendlyName, &nameVar);
 
 		if (SUCCEEDED(res)) {
+			size_t len = wcslen(nameVar.pwszVal);
 			size_t size;
 
-			size = os_wcs_to_utf8(nameVar.pwszVal, 0, nullptr);
-			if (size) {
-				device_name.resize(size);
-				os_wcs_to_utf8(nameVar.pwszVal, size,
-						&device_name[0]);
-			}
+			size = os_wcs_to_utf8(nameVar.pwszVal, len,
+					nullptr, 0) + 1;
+			device_name.resize(size);
+			os_wcs_to_utf8(nameVar.pwszVal, len,
+					&device_name[0], size);
 		}
 	}
 
@@ -61,7 +61,7 @@ void GetWASAPIAudioDevices_(vector<AudioDeviceInfo> &devices, bool input)
 		ComPtr<IMMDevice>   device;
 		CoTaskMemPtr<WCHAR> w_id;
 		AudioDeviceInfo     info;
-		size_t              size;
+		size_t              len, size;
 
 		res = collection->Item(i, device.Assign());
 		if (FAILED(res))
@@ -73,9 +73,10 @@ void GetWASAPIAudioDevices_(vector<AudioDeviceInfo> &devices, bool input)
 
 		info.name = GetDeviceName(device);
 
-		size = os_wcs_to_utf8(w_id, 0, nullptr);
+		len  = wcslen(w_id);
+		size = os_wcs_to_utf8(w_id, len, nullptr, 0) + 1;
 		info.id.resize(size);
-		os_wcs_to_utf8(w_id, size, &info.id[0]);
+		os_wcs_to_utf8(w_id, len, &info.id[0], size);
 
 		devices.push_back(info);
 	}