Fix multiple CVE issues
CVE-2022-39316, CVE-2022-39317: Add missing length checks in zgfx CVE-2022-39318: Fix division by zero in urbdrc channel CVE-2022-39319: Add missing length checks in urbdrc channel CVE-2022-39320: Ensure urb_create_iocompletion uses size_t CVE-2022-39347: Fix path validation in drive channel CVE-2022-41877: Add missing length check in drive channel Resolves: #2145140
This commit is contained in:
parent
0657b181a4
commit
916e606784
62
Added-function-_wcsncmp.patch
Normal file
62
Added-function-_wcsncmp.patch
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
From e482b394efc371412ce659b731a9b1e1d73bdf0e Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Mon, 24 Oct 2022 10:42:56 +0200
|
||||||
|
Subject: [PATCH] Added function _wcsncmp
|
||||||
|
|
||||||
|
* Compare WCHAR strings up to n characters
|
||||||
|
|
||||||
|
(cherry picked from commit 8178ed26a459356ece17414c6e871a7e0735a4ec)
|
||||||
|
---
|
||||||
|
winpr/include/winpr/string.h | 2 ++
|
||||||
|
winpr/libwinpr/crt/string.c | 15 ++++++++++++++-
|
||||||
|
2 files changed, 16 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h
|
||||||
|
index 8ce83bc1d..3b907c444 100644
|
||||||
|
--- a/winpr/include/winpr/string.h
|
||||||
|
+++ b/winpr/include/winpr/string.h
|
||||||
|
@@ -57,6 +57,7 @@ extern "C"
|
||||||
|
WINPR_API int _strnicmp(const char* string1, const char* string2, size_t count);
|
||||||
|
|
||||||
|
WINPR_API int _wcscmp(const WCHAR* string1, const WCHAR* string2);
|
||||||
|
+ WINPR_API int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count);
|
||||||
|
|
||||||
|
WINPR_API size_t _wcslen(const WCHAR* str);
|
||||||
|
WINPR_API size_t _wcsnlen(const WCHAR* str, size_t maxNumberOfElements);
|
||||||
|
@@ -70,6 +71,7 @@ extern "C"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define _wcscmp wcscmp
|
||||||
|
+#define _wcsncmp wcsncmp
|
||||||
|
#define _wcslen wcslen
|
||||||
|
#define _wcsnlen wcsnlen
|
||||||
|
#define _wcschr wcschr
|
||||||
|
diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c
|
||||||
|
index 37fcb4b25..c25ffa279 100644
|
||||||
|
--- a/winpr/libwinpr/crt/string.c
|
||||||
|
+++ b/winpr/libwinpr/crt/string.c
|
||||||
|
@@ -90,7 +90,20 @@ int _wcscmp(const WCHAR* string1, const WCHAR* string2)
|
||||||
|
|
||||||
|
Data_Read_UINT16(string1, value1);
|
||||||
|
Data_Read_UINT16(string2, value2);
|
||||||
|
- return value1 - value2;
|
||||||
|
+ return (int)value1 - value2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||||
|
+{
|
||||||
|
+ for (size_t x = 0; x < count; x++)
|
||||||
|
+ {
|
||||||
|
+ const WCHAR a = string1[x];
|
||||||
|
+ const WCHAR b = string2[x];
|
||||||
|
+
|
||||||
|
+ if (a != b)
|
||||||
|
+ return (int)a - b;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _wcslen -> wcslen */
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
29
Added-missing-length-check-in-urb_control_transfer.patch
Normal file
29
Added-missing-length-check-in-urb_control_transfer.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From 8c513f127549433c830575202d1551b0e9dd182d Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 13 Oct 2022 09:00:48 +0200
|
||||||
|
Subject: [PATCH] Added missing length check in urb_control_transfer
|
||||||
|
|
||||||
|
(cherry picked from commit ce838e2477cb8173ea5e98f35ad55ff41ea5117d)
|
||||||
|
---
|
||||||
|
channels/urbdrc/client/data_transfer.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c
|
||||||
|
index 9a44e6e09..bb2784055 100644
|
||||||
|
--- a/channels/urbdrc/client/data_transfer.c
|
||||||
|
+++ b/channels/urbdrc/client/data_transfer.c
|
||||||
|
@@ -673,7 +673,11 @@ static UINT urb_control_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callba
|
||||||
|
buffer = Stream_Pointer(out);
|
||||||
|
|
||||||
|
if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||||
|
+ {
|
||||||
|
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||||
|
+ return ERROR_INVALID_DATA;
|
||||||
|
Stream_Copy(s, out, OutputBufferSize);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/** process TS_URB_CONTROL_TRANSFER */
|
||||||
|
if (!pdev->control_transfer(pdev, RequestId, EndpointAddress, TransferFlags, bmRequestType,
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
51
Added-missing-length-checks-in-zgfx_decompress_segme.patch
Normal file
51
Added-missing-length-checks-in-zgfx_decompress_segme.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
From babbd1e433d273634637f5199429986714864033 Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 13 Oct 2022 09:09:28 +0200
|
||||||
|
Subject: [PATCH] Added missing length checks in zgfx_decompress_segment
|
||||||
|
|
||||||
|
(cherry picked from commit 64716b335858109d14f27b51acc4c4d71a92a816)
|
||||||
|
---
|
||||||
|
libfreerdp/codec/zgfx.c | 11 +++++++----
|
||||||
|
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c
|
||||||
|
index 1a2878bd9..04ddeadb2 100644
|
||||||
|
--- a/libfreerdp/codec/zgfx.c
|
||||||
|
+++ b/libfreerdp/codec/zgfx.c
|
||||||
|
@@ -230,19 +230,19 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||||
|
BYTE* pbSegment;
|
||||||
|
size_t cbSegment;
|
||||||
|
|
||||||
|
- if (!zgfx || !stream)
|
||||||
|
+ if (!zgfx || !stream || (segmentSize < 2))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cbSegment = segmentSize - 1;
|
||||||
|
|
||||||
|
- if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1) ||
|
||||||
|
- (segmentSize > UINT32_MAX))
|
||||||
|
+ if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize > UINT32_MAX))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Stream_Read_UINT8(stream, flags); /* header (1 byte) */
|
||||||
|
zgfx->OutputCount = 0;
|
||||||
|
pbSegment = Stream_Pointer(stream);
|
||||||
|
- Stream_Seek(stream, cbSegment);
|
||||||
|
+ if (!Stream_SafeSeek(stream, cbSegment))
|
||||||
|
+ return FALSE;
|
||||||
|
|
||||||
|
if (!(flags & PACKET_COMPRESSED))
|
||||||
|
{
|
||||||
|
@@ -346,6 +346,9 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||||
|
if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
+ if (count > zgfx->cBitsRemaining / 8)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent,
|
||||||
|
count);
|
||||||
|
zgfx_history_buffer_ring_write(zgfx, zgfx->pbInputCurrent, count);
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
32
Ensure-urb_create_iocompletion-uses-size_t-for-calcu.patch
Normal file
32
Ensure-urb_create_iocompletion-uses-size_t-for-calcu.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From b3a695e9f38a42f1ef0cade0d5e1fe60cf68864e Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 13 Oct 2022 08:36:26 +0200
|
||||||
|
Subject: [PATCH] Ensure urb_create_iocompletion uses size_t for calculation
|
||||||
|
|
||||||
|
(cherry picked from commit de7e0f062ee53d00b4a966a43855a716e3478150)
|
||||||
|
---
|
||||||
|
channels/urbdrc/client/data_transfer.c | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c
|
||||||
|
index 80e84af48..8642c8506 100644
|
||||||
|
--- a/channels/urbdrc/client/data_transfer.c
|
||||||
|
+++ b/channels/urbdrc/client/data_transfer.c
|
||||||
|
@@ -97,7 +97,13 @@ static wStream* urb_create_iocompletion(UINT32 InterfaceField, UINT32 MessageId,
|
||||||
|
UINT32 OutputBufferSize)
|
||||||
|
{
|
||||||
|
const UINT32 InterfaceId = (STREAM_ID_PROXY << 30) | (InterfaceField & 0x3FFFFFFF);
|
||||||
|
- wStream* out = Stream_New(NULL, OutputBufferSize + 28);
|
||||||
|
+
|
||||||
|
+#if UINT32_MAX >= SIZE_MAX
|
||||||
|
+ if (OutputBufferSize > UINT32_MAX - 28ull)
|
||||||
|
+ return NULL;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ wStream* out = Stream_New(NULL, OutputBufferSize + 28ull);
|
||||||
|
|
||||||
|
if (!out)
|
||||||
|
return NULL;
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
39
Fixed-division-by-zero-in-urbdrc.patch
Normal file
39
Fixed-division-by-zero-in-urbdrc.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From b9c5e3668c4022b34734ac8ccb07dd044d4ff38c Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 13 Oct 2022 08:27:41 +0200
|
||||||
|
Subject: [PATCH] Fixed division by zero in urbdrc
|
||||||
|
|
||||||
|
(cherry picked from commit 731f8419d04b481d7160de1f34062d630ed48765)
|
||||||
|
---
|
||||||
|
channels/urbdrc/client/libusb/libusb_udevice.c | 12 +++++++++---
|
||||||
|
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||||
|
index aa69890ae..5784d9fe2 100644
|
||||||
|
--- a/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||||
|
+++ b/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||||
|
@@ -1214,12 +1214,18 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, URBDRC_CHANNEL_CALLBACK* c
|
||||||
|
if (!Buffer)
|
||||||
|
Stream_Seek(user_data->data, (NumberOfPackets * 12));
|
||||||
|
|
||||||
|
- iso_packet_size = BufferSize / NumberOfPackets;
|
||||||
|
- iso_transfer = libusb_alloc_transfer(NumberOfPackets);
|
||||||
|
+ if (NumberOfPackets > 0)
|
||||||
|
+ {
|
||||||
|
+ iso_packet_size = BufferSize / NumberOfPackets;
|
||||||
|
+ iso_transfer = libusb_alloc_transfer((int)NumberOfPackets);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (iso_transfer == NULL)
|
||||||
|
{
|
||||||
|
- WLog_Print(urbdrc->log, WLOG_ERROR, "Error: libusb_alloc_transfer.");
|
||||||
|
+ WLog_Print(urbdrc->log, WLOG_ERROR,
|
||||||
|
+ "Error: libusb_alloc_transfer [NumberOfPackets=%" PRIu32 ", BufferSize=%" PRIu32
|
||||||
|
+ " ]",
|
||||||
|
+ NumberOfPackets, BufferSize);
|
||||||
|
async_transfer_user_data_free(user_data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
58
Fixed-missing-input-buffer-length-check-in-urbdrc.patch
Normal file
58
Fixed-missing-input-buffer-length-check-in-urbdrc.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
From ddf9b3f852c31311f8d726012131f657c9857276 Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 13 Oct 2022 08:47:51 +0200
|
||||||
|
Subject: [PATCH] Fixed missing input buffer length check in urbdrc
|
||||||
|
|
||||||
|
(cherry picked from commit 497df00f741dd4fc89292aaef2db7368aee45d0d)
|
||||||
|
---
|
||||||
|
channels/urbdrc/client/data_transfer.c | 20 ++++++++++++++++++++
|
||||||
|
1 file changed, 20 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c
|
||||||
|
index bb2784055..80e84af48 100644
|
||||||
|
--- a/channels/urbdrc/client/data_transfer.c
|
||||||
|
+++ b/channels/urbdrc/client/data_transfer.c
|
||||||
|
@@ -241,6 +241,10 @@ static UINT urbdrc_process_io_control(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* c
|
||||||
|
|
||||||
|
Stream_Read_UINT32(s, OutputBufferSize);
|
||||||
|
Stream_Read_UINT32(s, RequestId);
|
||||||
|
+
|
||||||
|
+ if (OutputBufferSize > UINT32_MAX - 4)
|
||||||
|
+ return ERROR_INVALID_DATA;
|
||||||
|
+
|
||||||
|
InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
|
||||||
|
out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, OutputBufferSize + 4);
|
||||||
|
|
||||||
|
@@ -724,6 +728,15 @@ static UINT urb_bulk_or_interrupt_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBA
|
||||||
|
Stream_Read_UINT32(s, TransferFlags); /** TransferFlags */
|
||||||
|
Stream_Read_UINT32(s, OutputBufferSize);
|
||||||
|
EndpointAddress = (PipeHandle & 0x000000ff);
|
||||||
|
+
|
||||||
|
+ if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||||
|
+ {
|
||||||
|
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||||
|
+ {
|
||||||
|
+ return ERROR_INVALID_DATA;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/** process TS_URB_BULK_OR_INTERRUPT_TRANSFER */
|
||||||
|
return pdev->bulk_or_interrupt_transfer(
|
||||||
|
pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, noAck,
|
||||||
|
@@ -808,6 +821,13 @@ static UINT urb_isoch_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callback
|
||||||
|
packetDescriptorData = Stream_Pointer(s);
|
||||||
|
Stream_Seek(s, NumberOfPackets * 12);
|
||||||
|
Stream_Read_UINT32(s, OutputBufferSize);
|
||||||
|
+
|
||||||
|
+ if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||||
|
+ {
|
||||||
|
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||||
|
+ return ERROR_INVALID_DATA;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return pdev->isoch_transfer(
|
||||||
|
pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, StartFrame,
|
||||||
|
ErrorCount, noAck, packetDescriptorData, NumberOfPackets, OutputBufferSize,
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
28
Fixed-missing-stream-length-check-in-drive_file_quer.patch
Normal file
28
Fixed-missing-stream-length-check-in-drive_file_quer.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From 80b2483373c00baec3a26b1d82027f16dfdd8859 Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Mon, 24 Oct 2022 08:45:05 +0200
|
||||||
|
Subject: [PATCH] Fixed missing stream length check in
|
||||||
|
drive_file_query_directory
|
||||||
|
|
||||||
|
(cherry picked from commit 4e4bb79795d6ac85473fb7a83e53ccf63d204b93)
|
||||||
|
---
|
||||||
|
channels/drive/client/drive_main.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c
|
||||||
|
index d3776381c..b6cf2ad32 100644
|
||||||
|
--- a/channels/drive/client/drive_main.c
|
||||||
|
+++ b/channels/drive/client/drive_main.c
|
||||||
|
@@ -629,6 +629,9 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
|
||||||
|
Stream_Read_UINT32(irp->input, PathLength);
|
||||||
|
Stream_Seek(irp->input, 23); /* Padding */
|
||||||
|
path = (WCHAR*)Stream_Pointer(irp->input);
|
||||||
|
+ if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, PathLength))
|
||||||
|
+ return ERROR_INVALID_DATA;
|
||||||
|
+
|
||||||
|
file = drive_get_file_by_id(drive, irp->FileId);
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
288
Fixed-path-validation-in-drive-channel.patch
Normal file
288
Fixed-path-validation-in-drive-channel.patch
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
From 865ba07a0fd4fbc7a8203482411aacca3bbfbb9f Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Mon, 24 Oct 2022 10:41:55 +0200
|
||||||
|
Subject: [PATCH] Fixed path validation in drive channel
|
||||||
|
|
||||||
|
Check that canonical path is a subpath of the shared directory
|
||||||
|
|
||||||
|
(cherry picked from commit 844c94e6d0438fa7bd8ff8d5513c3f69c3018b85)
|
||||||
|
---
|
||||||
|
channels/drive/client/drive_file.c | 106 ++++++++++++++++++-----------
|
||||||
|
channels/drive/client/drive_file.h | 8 +--
|
||||||
|
channels/drive/client/drive_main.c | 8 +--
|
||||||
|
3 files changed, 73 insertions(+), 49 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c
|
||||||
|
index 305438593..1ea4ab9da 100644
|
||||||
|
--- a/channels/drive/client/drive_file.c
|
||||||
|
+++ b/channels/drive/client/drive_file.c
|
||||||
|
@@ -61,10 +61,14 @@
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-static void drive_file_fix_path(WCHAR* path)
|
||||||
|
+static BOOL drive_file_fix_path(WCHAR* path, size_t length)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
- size_t length = _wcslen(path);
|
||||||
|
+
|
||||||
|
+ if ((length == 0) || (length > UINT32_MAX))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ assert(path);
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
@@ -75,58 +79,82 @@ static void drive_file_fix_path(WCHAR* path)
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
if ((length == 3) && (path[1] == L':') && (path[2] == L'/'))
|
||||||
|
- return;
|
||||||
|
+ return FALSE;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if ((length == 1) && (path[0] == L'/'))
|
||||||
|
- return;
|
||||||
|
+ return FALSE;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((length > 0) && (path[length - 1] == L'/'))
|
||||||
|
path[length - 1] = L'\0';
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WCHAR* drive_file_combine_fullpath(const WCHAR* base_path, const WCHAR* path,
|
||||||
|
- size_t PathLength)
|
||||||
|
+ size_t PathWCharLength)
|
||||||
|
{
|
||||||
|
- WCHAR* fullpath;
|
||||||
|
- size_t base_path_length;
|
||||||
|
+ BOOL ok = FALSE;
|
||||||
|
+ WCHAR* fullpath = NULL;
|
||||||
|
+ size_t length;
|
||||||
|
|
||||||
|
- if (!base_path || (!path && (PathLength > 0)))
|
||||||
|
- return NULL;
|
||||||
|
+ if (!base_path || (!path && (PathWCharLength > 0)))
|
||||||
|
+ goto fail;
|
||||||
|
|
||||||
|
- base_path_length = _wcslen(base_path) * 2;
|
||||||
|
- fullpath = (WCHAR*)calloc(1, base_path_length + PathLength + sizeof(WCHAR));
|
||||||
|
+ const size_t base_path_length = _wcsnlen(base_path, MAX_PATH);
|
||||||
|
+ length = base_path_length + PathWCharLength + 1;
|
||||||
|
+ fullpath = (WCHAR*)calloc(length, sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!fullpath)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ CopyMemory(fullpath, base_path, base_path_length * sizeof(WCHAR));
|
||||||
|
+ if (path)
|
||||||
|
+ CopyMemory(&fullpath[base_path_length], path, PathWCharLength * sizeof(WCHAR));
|
||||||
|
+
|
||||||
|
+ if (!drive_file_fix_path(fullpath, length))
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ /* Ensure the path does not contain sequences like '..' */
|
||||||
|
+ const WCHAR dotdot[] = { '.', '.', '\0' };
|
||||||
|
+ if (_wcsstr(&fullpath[base_path_length], dotdot))
|
||||||
|
{
|
||||||
|
- WLog_ERR(TAG, "malloc failed!");
|
||||||
|
- return NULL;
|
||||||
|
+ char abuffer[MAX_PATH] = { 0 };
|
||||||
|
+ ConvertFromUnicode(CP_UTF8, 0, &fullpath[base_path_length], -1, (char**)&abuffer,
|
||||||
|
+ ARRAYSIZE(abuffer) - 1, NULL, NULL);
|
||||||
|
+
|
||||||
|
+ WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' from server, aborting!",
|
||||||
|
+ &abuffer[base_path_length]);
|
||||||
|
+ goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
- CopyMemory(fullpath, base_path, base_path_length);
|
||||||
|
- if (path)
|
||||||
|
- CopyMemory((char*)fullpath + base_path_length, path, PathLength);
|
||||||
|
- drive_file_fix_path(fullpath);
|
||||||
|
+ ok = TRUE;
|
||||||
|
+fail:
|
||||||
|
+ if (!ok)
|
||||||
|
+ {
|
||||||
|
+ free(fullpath);
|
||||||
|
+ fullpath = NULL;
|
||||||
|
+ }
|
||||||
|
return fullpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||||
|
{
|
||||||
|
- WIN32_FIND_DATAW findFileData;
|
||||||
|
+ WIN32_FIND_DATAW findFileData = { 0 };
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
- HANDLE dir;
|
||||||
|
- WCHAR* fullpath;
|
||||||
|
- WCHAR* path_slash;
|
||||||
|
- size_t base_path_length;
|
||||||
|
+ HANDLE dir = INVALID_HANDLE_VALUE;
|
||||||
|
+ WCHAR* fullpath = NULL;
|
||||||
|
+ WCHAR* path_slash = NULL;
|
||||||
|
+ size_t base_path_length = 0;
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
- base_path_length = _wcslen(path) * 2;
|
||||||
|
- path_slash = (WCHAR*)calloc(1, base_path_length + sizeof(WCHAR) * 3);
|
||||||
|
+ base_path_length = _wcslen(path);
|
||||||
|
+ path_slash = (WCHAR*)calloc(base_path_length + 3, sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!path_slash)
|
||||||
|
{
|
||||||
|
@@ -134,12 +162,11 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- CopyMemory(path_slash, path, base_path_length);
|
||||||
|
- path_slash[base_path_length / 2] = L'/';
|
||||||
|
- path_slash[base_path_length / 2 + 1] = L'*';
|
||||||
|
+ CopyMemory(path_slash, path, base_path_length * sizeof(WCHAR));
|
||||||
|
+ path_slash[base_path_length] = L'/';
|
||||||
|
+ path_slash[base_path_length + 1] = L'*';
|
||||||
|
DEBUG_WSTR("Search in %s", path_slash);
|
||||||
|
dir = FindFirstFileW(path_slash, &findFileData);
|
||||||
|
- path_slash[base_path_length / 2 + 1] = 0;
|
||||||
|
|
||||||
|
if (dir == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
@@ -149,7 +176,7 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
- size_t len = _wcslen(findFileData.cFileName);
|
||||||
|
+ const size_t len = _wcsnlen(findFileData.cFileName, ARRAYSIZE(findFileData.cFileName));
|
||||||
|
|
||||||
|
if ((len == 1 && findFileData.cFileName[0] == L'.') ||
|
||||||
|
(len == 2 && findFileData.cFileName[0] == L'.' && findFileData.cFileName[1] == L'.'))
|
||||||
|
@@ -157,7 +184,7 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len * 2);
|
||||||
|
+ fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len);
|
||||||
|
DEBUG_WSTR("Delete %s", fullpath);
|
||||||
|
|
||||||
|
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
@@ -333,13 +360,13 @@ static BOOL drive_file_init(DRIVE_FILE* file)
|
||||||
|
return file->file_handle != INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||||
|
- UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||||
|
- UINT32 FileAttributes, UINT32 SharedAccess)
|
||||||
|
+DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||||
|
+ UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||||
|
+ UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess)
|
||||||
|
{
|
||||||
|
DRIVE_FILE* file;
|
||||||
|
|
||||||
|
- if (!base_path || (!path && (PathLength > 0)))
|
||||||
|
+ if (!base_path || (!path && (PathWCharLength > 0)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
file = (DRIVE_FILE*)calloc(1, sizeof(DRIVE_FILE));
|
||||||
|
@@ -359,7 +386,7 @@ DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 Pat
|
||||||
|
file->CreateDisposition = CreateDisposition;
|
||||||
|
file->CreateOptions = CreateOptions;
|
||||||
|
file->SharedAccess = SharedAccess;
|
||||||
|
- drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathLength));
|
||||||
|
+ drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathWCharLength));
|
||||||
|
|
||||||
|
if (!drive_file_init(file))
|
||||||
|
{
|
||||||
|
@@ -714,13 +741,10 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
fullpath = drive_file_combine_fullpath(file->basepath, (WCHAR*)Stream_Pointer(input),
|
||||||
|
- FileNameLength);
|
||||||
|
+ FileNameLength / sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!fullpath)
|
||||||
|
- {
|
||||||
|
- WLog_ERR(TAG, "drive_file_combine_fullpath failed!");
|
||||||
|
return FALSE;
|
||||||
|
- }
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
@@ -759,7 +783,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||||
|
- const WCHAR* path, UINT32 PathLength, wStream* output)
|
||||||
|
+ const WCHAR* path, UINT32 PathWCharLength, wStream* output)
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
WCHAR* ent_path;
|
||||||
|
@@ -773,7 +797,7 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
||||||
|
if (file->find_handle != INVALID_HANDLE_VALUE)
|
||||||
|
FindClose(file->find_handle);
|
||||||
|
|
||||||
|
- ent_path = drive_file_combine_fullpath(file->basepath, path, PathLength);
|
||||||
|
+ ent_path = drive_file_combine_fullpath(file->basepath, path, PathWCharLength);
|
||||||
|
/* open new search handle and retrieve the first entry */
|
||||||
|
file->find_handle = FindFirstFileW(ent_path, &file->find_data);
|
||||||
|
free(ent_path);
|
||||||
|
diff --git a/channels/drive/client/drive_file.h b/channels/drive/client/drive_file.h
|
||||||
|
index ed789d6f0..6d3bd7045 100644
|
||||||
|
--- a/channels/drive/client/drive_file.h
|
||||||
|
+++ b/channels/drive/client/drive_file.h
|
||||||
|
@@ -51,9 +51,9 @@ struct _DRIVE_FILE
|
||||||
|
UINT32 CreateOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
-DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||||
|
- UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||||
|
- UINT32 FileAttributes, UINT32 SharedAccess);
|
||||||
|
+DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||||
|
+ UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||||
|
+ UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess);
|
||||||
|
BOOL drive_file_free(DRIVE_FILE* file);
|
||||||
|
|
||||||
|
BOOL drive_file_open(DRIVE_FILE* file);
|
||||||
|
@@ -64,6 +64,6 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
||||||
|
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
|
||||||
|
wStream* input);
|
||||||
|
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||||
|
- const WCHAR* path, UINT32 PathLength, wStream* output);
|
||||||
|
+ const WCHAR* path, UINT32 PathWCharLength, wStream* output);
|
||||||
|
|
||||||
|
#endif /* FREERDP_CHANNEL_DRIVE_FILE_H */
|
||||||
|
diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c
|
||||||
|
index 1b5422522..d3776381c 100644
|
||||||
|
--- a/channels/drive/client/drive_main.c
|
||||||
|
+++ b/channels/drive/client/drive_main.c
|
||||||
|
@@ -184,8 +184,8 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
|
||||||
|
|
||||||
|
path = (const WCHAR*)Stream_Pointer(irp->input);
|
||||||
|
FileId = irp->devman->id_sequence++;
|
||||||
|
- file = drive_file_new(drive->path, path, PathLength, FileId, DesiredAccess, CreateDisposition,
|
||||||
|
- CreateOptions, FileAttributes, SharedAccess);
|
||||||
|
+ file = drive_file_new(drive->path, path, PathLength / sizeof(WCHAR), FileId, DesiredAccess,
|
||||||
|
+ CreateDisposition, CreateOptions, FileAttributes, SharedAccess);
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
@@ -636,8 +636,8 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
|
||||||
|
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||||
|
Stream_Write_UINT32(irp->output, 0); /* Length */
|
||||||
|
}
|
||||||
|
- else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path, PathLength,
|
||||||
|
- irp->output))
|
||||||
|
+ else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path,
|
||||||
|
+ PathLength / sizeof(WCHAR), irp->output))
|
||||||
|
{
|
||||||
|
irp->IoStatus = drive_map_windows_err(GetLastError());
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
18
freerdp.spec
18
freerdp.spec
@ -46,6 +46,18 @@ Patch4: Fix-length-checks-in-parallel-driver.patch
|
|||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2136154
|
# https://bugzilla.redhat.com/show_bug.cgi?id=2136154
|
||||||
Patch5: Fixed-missing-length-check-in-video-channel.patch
|
Patch5: Fixed-missing-length-check-in-video-channel.patch
|
||||||
|
|
||||||
|
# https://bugzilla.redhat.com/show_bug.cgi?id=2145140
|
||||||
|
Patch6: Added-missing-length-checks-in-zgfx_decompress_segme.patch
|
||||||
|
Patch7: Fixed-division-by-zero-in-urbdrc.patch
|
||||||
|
Patch8: Added-missing-length-check-in-urb_control_transfer.patch
|
||||||
|
Patch9: Fixed-missing-input-buffer-length-check-in-urbdrc.patch
|
||||||
|
Patch10: Ensure-urb_create_iocompletion-uses-size_t-for-calcu.patch
|
||||||
|
Patch11: Added-function-_wcsncmp.patch
|
||||||
|
Patch12: winpr-crt-Fix-wcs-cmp-and-wcs-len-checks.patch
|
||||||
|
Patch13: winpr-crt-Added-wcsstr-implementation.patch
|
||||||
|
Patch14: Fixed-path-validation-in-drive-channel.patch
|
||||||
|
Patch15: Fixed-missing-stream-length-check-in-drive_file_quer.patch
|
||||||
|
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
BuildRequires: gcc-c++
|
BuildRequires: gcc-c++
|
||||||
BuildRequires: alsa-lib-devel
|
BuildRequires: alsa-lib-devel
|
||||||
@ -314,6 +326,12 @@ find %{buildroot} -name "*.a" -delete
|
|||||||
* Thu Dec 08 2022 Ondrej Holy <oholy@redhat.com> - - 2:2.4.1-4
|
* Thu Dec 08 2022 Ondrej Holy <oholy@redhat.com> - - 2:2.4.1-4
|
||||||
- CVE-2022-39282: Fix length checks in parallel driver (#2136152)
|
- CVE-2022-39282: Fix length checks in parallel driver (#2136152)
|
||||||
- CVE-2022-39283: Add missing length check in video channel (#2136154)
|
- CVE-2022-39283: Add missing length check in video channel (#2136154)
|
||||||
|
- CVE-2022-39316, CVE-2022-39317: Add missing length checks in zgfx (#2145140)
|
||||||
|
- CVE-2022-39318: Fix division by zero in urbdrc channel (#2145140)
|
||||||
|
- CVE-2022-39319: Add missing length checks in urbdrc channel (#2145140)
|
||||||
|
- CVE-2022-39320: Ensure urb_create_iocompletion uses size_t (#2145140)
|
||||||
|
- CVE-2022-39347: Fix path validation in drive channel (#2145140)
|
||||||
|
- CVE-2022-41877: Add missing length check in drive channel (#2145140)
|
||||||
|
|
||||||
* Wed Jun 22 2022 Ondrej Holy <oholy@redhat.com> - - 2:2.4.1-3
|
* Wed Jun 22 2022 Ondrej Holy <oholy@redhat.com> - - 2:2.4.1-3
|
||||||
- Fix gateway functionality with OpenSSL 3.0 (#2023262)
|
- Fix gateway functionality with OpenSSL 3.0 (#2023262)
|
||||||
|
66
winpr-crt-Added-wcsstr-implementation.patch
Normal file
66
winpr-crt-Added-wcsstr-implementation.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From ddc6dacd06b41ed5001b1c884b5d5c9e0a70e275 Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 10 Nov 2022 15:54:28 +0100
|
||||||
|
Subject: [PATCH] [winpr, crt] Added wcsstr implementation
|
||||||
|
|
||||||
|
(cherry picked from commit 6c034ba6117a4efc9266e845fe9a9a92ed4ee61d)
|
||||||
|
---
|
||||||
|
winpr/include/winpr/string.h | 3 +++
|
||||||
|
winpr/libwinpr/crt/string.c | 20 ++++++++++++++++++++
|
||||||
|
2 files changed, 23 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h
|
||||||
|
index 3b907c444..2d7126210 100644
|
||||||
|
--- a/winpr/include/winpr/string.h
|
||||||
|
+++ b/winpr/include/winpr/string.h
|
||||||
|
@@ -62,6 +62,8 @@ extern "C"
|
||||||
|
WINPR_API size_t _wcslen(const WCHAR* str);
|
||||||
|
WINPR_API size_t _wcsnlen(const WCHAR* str, size_t maxNumberOfElements);
|
||||||
|
|
||||||
|
+ WINPR_API WCHAR* _wcsstr(const WCHAR* str, const WCHAR* strSearch);
|
||||||
|
+
|
||||||
|
WINPR_API WCHAR* _wcschr(const WCHAR* str, WCHAR c);
|
||||||
|
WINPR_API WCHAR* _wcsrchr(const WCHAR* str, WCHAR c);
|
||||||
|
|
||||||
|
@@ -74,6 +76,7 @@ extern "C"
|
||||||
|
#define _wcsncmp wcsncmp
|
||||||
|
#define _wcslen wcslen
|
||||||
|
#define _wcsnlen wcsnlen
|
||||||
|
+#define _wcsstr wcsstr
|
||||||
|
#define _wcschr wcschr
|
||||||
|
#define _wcsrchr wcsrchr
|
||||||
|
|
||||||
|
diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c
|
||||||
|
index 5dcf4b3f1..efd7d166c 100644
|
||||||
|
--- a/winpr/libwinpr/crt/string.c
|
||||||
|
+++ b/winpr/libwinpr/crt/string.c
|
||||||
|
@@ -147,6 +147,26 @@ size_t _wcsnlen(const WCHAR* str, size_t max)
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* _wcsstr -> wcsstr */
|
||||||
|
+
|
||||||
|
+WCHAR* _wcsstr(const WCHAR* str, const WCHAR* strSearch)
|
||||||
|
+{
|
||||||
|
+ assert(str);
|
||||||
|
+ assert(strSearch);
|
||||||
|
+
|
||||||
|
+ if (strSearch[0] == '\0')
|
||||||
|
+ return str;
|
||||||
|
+
|
||||||
|
+ const size_t searchLen = _wcslen(strSearch);
|
||||||
|
+ while (*str)
|
||||||
|
+ {
|
||||||
|
+ if (_wcsncmp(str, strSearch, searchLen) == 0)
|
||||||
|
+ return str;
|
||||||
|
+ str++;
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* _wcschr -> wcschr */
|
||||||
|
|
||||||
|
WCHAR* _wcschr(const WCHAR* str, WCHAR c)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
90
winpr-crt-Fix-wcs-cmp-and-wcs-len-checks.patch
Normal file
90
winpr-crt-Fix-wcs-cmp-and-wcs-len-checks.patch
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
From fb9d753af70b449dd7a17898d46fd57822a08dc1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 10 Nov 2022 14:21:22 +0100
|
||||||
|
Subject: [PATCH] [winpr, crt] Fix wcs*cmp and wcs*len checks
|
||||||
|
|
||||||
|
(cherry picked from commit b60fac1a0470fe83e8d0b448f0fd7e9e6d6a0f96)
|
||||||
|
---
|
||||||
|
winpr/libwinpr/crt/string.c | 30 +++++++++++++++++++-----------
|
||||||
|
1 file changed, 19 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c
|
||||||
|
index c25ffa279..5dcf4b3f1 100644
|
||||||
|
--- a/winpr/libwinpr/crt/string.c
|
||||||
|
+++ b/winpr/libwinpr/crt/string.c
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#include <wctype.h>
|
||||||
|
|
||||||
|
#include <winpr/crt.h>
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <winpr/endian.h>
|
||||||
|
|
||||||
|
/* String Manipulation (CRT): http://msdn.microsoft.com/en-us/library/f0151s4x.aspx */
|
||||||
|
@@ -80,21 +81,28 @@ int _strnicmp(const char* string1, const char* string2, size_t count)
|
||||||
|
|
||||||
|
int _wcscmp(const WCHAR* string1, const WCHAR* string2)
|
||||||
|
{
|
||||||
|
- WCHAR value1, value2;
|
||||||
|
+ assert(string1);
|
||||||
|
+ assert(string2);
|
||||||
|
|
||||||
|
- while (*string1 && (*string1 == *string2))
|
||||||
|
+ while (TRUE)
|
||||||
|
{
|
||||||
|
- string1++;
|
||||||
|
- string2++;
|
||||||
|
+ const WCHAR w1 = *string1++;
|
||||||
|
+ const WCHAR w2 = *string2++;
|
||||||
|
+
|
||||||
|
+ if (w1 != w2)
|
||||||
|
+ return (int)w1 - w2;
|
||||||
|
+ else if ((w1 == '\0') || (w2 == '\0'))
|
||||||
|
+ return (int)w1 - w2;
|
||||||
|
}
|
||||||
|
|
||||||
|
- Data_Read_UINT16(string1, value1);
|
||||||
|
- Data_Read_UINT16(string2, value2);
|
||||||
|
- return (int)value1 - value2;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||||
|
{
|
||||||
|
+ assert(string1);
|
||||||
|
+ assert(string2);
|
||||||
|
+
|
||||||
|
for (size_t x = 0; x < count; x++)
|
||||||
|
{
|
||||||
|
const WCHAR a = string1[x];
|
||||||
|
@@ -102,6 +110,8 @@ int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||||
|
|
||||||
|
if (a != b)
|
||||||
|
return (int)a - b;
|
||||||
|
+ else if ((a == '\0') || (b == '\0'))
|
||||||
|
+ return (int)a - b;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -112,8 +122,7 @@ size_t _wcslen(const WCHAR* str)
|
||||||
|
{
|
||||||
|
const WCHAR* p = (const WCHAR*)str;
|
||||||
|
|
||||||
|
- if (!p)
|
||||||
|
- return 0;
|
||||||
|
+ assert(p);
|
||||||
|
|
||||||
|
while (*p)
|
||||||
|
p++;
|
||||||
|
@@ -127,8 +136,7 @@ size_t _wcsnlen(const WCHAR* str, size_t max)
|
||||||
|
{
|
||||||
|
size_t x;
|
||||||
|
|
||||||
|
- if (!str)
|
||||||
|
- return 0;
|
||||||
|
+ assert(str);
|
||||||
|
|
||||||
|
for (x = 0; x < max; x++)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user