|
From: selvanair (C. Review) <ge...@op...> - 2025-10-27 20:34:49
|
Attention is currently required from: flichtenheld, plaisthos.
Hello plaisthos, flichtenheld,
I'd like you to do a code review.
Please visit
http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email
to review the following change.
Change subject: Canonicalize config_dir before comparing with the config file location
......................................................................
Canonicalize config_dir before comparing with the config file location
Found by ZeroPath
Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386
Signed-off-by: Selva Nair <sel...@gm...>
---
M src/openvpnserv/CMakeLists.txt
M src/openvpnserv/validate.c
2 files changed, 17 insertions(+), 4 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/18/1318/1
diff --git a/src/openvpnserv/CMakeLists.txt b/src/openvpnserv/CMakeLists.txt
index 340b904..a92ee08 100644
--- a/src/openvpnserv/CMakeLists.txt
+++ b/src/openvpnserv/CMakeLists.txt
@@ -6,6 +6,11 @@
add_executable(openvpnserv)
+include(CheckSymbolExists)
+
+# Some old versions of mingw does not have PATHCCH_OPTIONS enums -- add a check
+check_symbol_exists(PATHCCH_ENSURE_TRAILING_SLASH pathcch.h HAVE_PATHCCH_ENSURE_TRAILING_SLASH)
+
set(MC_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/mc)
target_include_directories(openvpnserv PRIVATE
@@ -31,7 +36,7 @@
)
target_link_libraries(openvpnserv
advapi32.lib userenv.lib iphlpapi.lib fwpuclnt.lib rpcrt4.lib
- shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib)
+ shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib pathcch.lib)
if (MINGW)
target_compile_options(openvpnserv PRIVATE -municode)
target_link_options(openvpnserv PRIVATE -municode)
diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c
index 59d5b86..2187fb5 100644
--- a/src/openvpnserv/validate.c
+++ b/src/openvpnserv/validate.c
@@ -25,6 +25,11 @@
#include <lmaccess.h>
#include <shlwapi.h>
#include <lm.h>
+#include <pathcch.h>
+
+#ifndef HAVE_PATHCCH_ENSURE_TRAILING_SLASH
+#define PATHCCH_ENSURE_TRAILING_SLASH 0x20
+#endif
static const WCHAR *white_list[] = {
L"auth-retry",
@@ -61,7 +66,7 @@
{
WCHAR tmp[MAX_PATH];
const WCHAR *config_file = NULL;
- const WCHAR *config_dir = NULL;
+ WCHAR config_dir[MAX_PATH];
/* convert fname to full path */
if (PathIsRelativeW(fname))
@@ -74,9 +79,12 @@
config_file = fname;
}
- config_dir = s->config_dir;
+ /* canonicalize config_dir and add trailing slash before comparison */
+ HRESULT res = PathCchCanonicalizeEx(config_dir, _countof(config_dir), s->config_dir,
+ PATHCCH_ENSURE_TRAILING_SLASH);
- if (wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0
+ if (res == S_OK
+ && wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0
&& wcsstr(config_file + wcslen(config_dir), L"..") == NULL)
{
return TRUE;
--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email
To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386
Gerrit-Change-Number: 1318
Gerrit-PatchSet: 1
Gerrit-Owner: selvanair <sel...@gm...>
Gerrit-Reviewer: flichtenheld <fr...@li...>
Gerrit-Reviewer: plaisthos <arn...@rf...>
Gerrit-CC: openvpn-devel <ope...@li...>
Gerrit-Attention: plaisthos <arn...@rf...>
Gerrit-Attention: flichtenheld <fr...@li...>
|
|
From: plaisthos (C. Review) <ge...@op...> - 2025-10-27 21:13:14
|
Attention is currently required from: flichtenheld, selvanair. plaisthos has posted comments on this change by selvanair. ( http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email ) Change subject: Canonicalize config_dir before comparing with the config file location ...................................................................... Patch Set 1: Code-Review+1 (1 comment) File src/openvpnserv/validate.c: http://gerrit.openvpn.net/c/openvpn/+/1318/comment/4804eff4_88a77403?usp=email : PS1, Line 32: #endif Any reason that we cannot just do #ifndef PATHCCH_ENSURE_TRAILING_SLASH here and have to do the cmake dance? -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: comment Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Gerrit-Change-Number: 1318 Gerrit-PatchSet: 1 Gerrit-Owner: selvanair <sel...@gm...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Attention: selvanair <sel...@gm...> Gerrit-Comment-Date: Mon, 27 Oct 2025 21:13:04 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes |
|
From: selvanair (C. Review) <ge...@op...> - 2025-10-27 21:57:09
|
Attention is currently required from: flichtenheld, plaisthos. selvanair has posted comments on this change by selvanair. ( http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email ) Change subject: Canonicalize config_dir before comparing with the config file location ...................................................................... Patch Set 1: (1 comment) File src/openvpnserv/validate.c: http://gerrit.openvpn.net/c/openvpn/+/1318/comment/d1f80050_27c71e51?usp=email : PS1, Line 32: #endif > Any reason that we cannot just do #ifndef PATHCCH_ENSURE_TRAILING_SLASH here and have to do the cmak […] When its defined, its an enum in pathcch.h, not a define. mingw does have it now, but apparently not in ubuntu 24.04 that we use. -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: comment Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Gerrit-Change-Number: 1318 Gerrit-PatchSet: 1 Gerrit-Owner: selvanair <sel...@gm...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Mon, 27 Oct 2025 21:56:55 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: plaisthos <arn...@rf...> |
|
From: plaisthos (C. Review) <ge...@op...> - 2025-10-27 22:11:24
|
Attention is currently required from: flichtenheld, selvanair. plaisthos has posted comments on this change by selvanair. ( http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email ) Change subject: Canonicalize config_dir before comparing with the config file location ...................................................................... Patch Set 1: Code-Review+2 (1 comment) File src/openvpnserv/validate.c: http://gerrit.openvpn.net/c/openvpn/+/1318/comment/a259ecd3_08086e9f?usp=email : PS1, Line 32: #endif > When its defined, its an enum in pathcch.h, not a define. […] Acknowledged -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: comment Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Gerrit-Change-Number: 1318 Gerrit-PatchSet: 1 Gerrit-Owner: selvanair <sel...@gm...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Attention: selvanair <sel...@gm...> Gerrit-Comment-Date: Mon, 27 Oct 2025 22:11:14 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Comment-In-Reply-To: plaisthos <arn...@rf...> Comment-In-Reply-To: selvanair <sel...@gm...> |
|
From: Gert D. <ge...@gr...> - 2025-10-28 10:16:50
|
From: Selva Nair <sel...@gm...> Found by ZeroPath Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Signed-off-by: Selva Nair <sel...@gm...> Acked-by: Arne Schwabe <arn...@rf...> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1318 --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1318 This mail reflects revision 1 of this Change. Acked-by according to Gerrit (reflected above): Arne Schwabe <arn...@rf...> diff --git a/src/openvpnserv/CMakeLists.txt b/src/openvpnserv/CMakeLists.txt index 340b904..a92ee08 100644 --- a/src/openvpnserv/CMakeLists.txt +++ b/src/openvpnserv/CMakeLists.txt @@ -6,6 +6,11 @@ add_executable(openvpnserv) +include(CheckSymbolExists) + +# Some old versions of mingw does not have PATHCCH_OPTIONS enums -- add a check +check_symbol_exists(PATHCCH_ENSURE_TRAILING_SLASH pathcch.h HAVE_PATHCCH_ENSURE_TRAILING_SLASH) + set(MC_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/mc) target_include_directories(openvpnserv PRIVATE @@ -31,7 +36,7 @@ ) target_link_libraries(openvpnserv advapi32.lib userenv.lib iphlpapi.lib fwpuclnt.lib rpcrt4.lib - shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib) + shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib pathcch.lib) if (MINGW) target_compile_options(openvpnserv PRIVATE -municode) target_link_options(openvpnserv PRIVATE -municode) diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c index 59d5b86..2187fb5 100644 --- a/src/openvpnserv/validate.c +++ b/src/openvpnserv/validate.c @@ -25,6 +25,11 @@ #include <lmaccess.h> #include <shlwapi.h> #include <lm.h> +#include <pathcch.h> + +#ifndef HAVE_PATHCCH_ENSURE_TRAILING_SLASH +#define PATHCCH_ENSURE_TRAILING_SLASH 0x20 +#endif static const WCHAR *white_list[] = { L"auth-retry", @@ -61,7 +66,7 @@ { WCHAR tmp[MAX_PATH]; const WCHAR *config_file = NULL; - const WCHAR *config_dir = NULL; + WCHAR config_dir[MAX_PATH]; /* convert fname to full path */ if (PathIsRelativeW(fname)) @@ -74,9 +79,12 @@ config_file = fname; } - config_dir = s->config_dir; + /* canonicalize config_dir and add trailing slash before comparison */ + HRESULT res = PathCchCanonicalizeEx(config_dir, _countof(config_dir), s->config_dir, + PATHCCH_ENSURE_TRAILING_SLASH); - if (wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0 + if (res == S_OK + && wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0 && wcsstr(config_file + wcslen(config_dir), L"..") == NULL) { return TRUE; |
|
From: Gert D. <ge...@gr...> - 2025-10-28 14:05:59
|
ACK from Arne, extra check from Lev, BB all green, so let's see if the
windows t_client test (run by github magic only after pushing to the official
repo...) finds something else.
Also, as Lev remarked, we might want to apply this to 2.6 "if 2.6 is broken
on windows 7 anyway" or see what to do about the original report on Win7,
if anything at all.
Your patch has been applied to the master branch.
commit 05a8ba8080c7a7c3dc6cc681b3fc3cf8c559e053
Author: Selva Nair
Date: Tue Oct 28 11:16:36 2025 +0100
Canonicalize config_dir before comparing with the config file location
Signed-off-by: Selva Nair <sel...@gm...>
Acked-by: Arne Schwabe <arn...@rf...>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1318
Message-Id: <202...@gr...>
URL: https://www.mail-archive.com/ope...@li.../msg33923.html
Signed-off-by: Gert Doering <ge...@gr...>
--
kind regards,
Gert Doering
|
|
From: stipa (C. Review) <ge...@op...> - 2025-10-28 13:39:27
|
Attention is currently required from: flichtenheld, selvanair. stipa has posted comments on this change by selvanair. ( http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email ) Change subject: Canonicalize config_dir before comparing with the config file location ...................................................................... Patch Set 1: Code-Review+2 (1 comment) Patchset: PS1: Looks good, but this API (PathCchCanonicalizeEx) is available starting from Windows 8. Let's merge it for master only - by default config_dir comes from the installer and terminates with "\", and you need admin rights to change it. So I think it is not that critical. -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: comment Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Gerrit-Change-Number: 1318 Gerrit-PatchSet: 1 Gerrit-Owner: selvanair <sel...@gm...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-Reviewer: stipa <lst...@gm...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Attention: selvanair <sel...@gm...> Gerrit-Comment-Date: Tue, 28 Oct 2025 13:39:17 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes |
|
From: cron2 (C. Review) <ge...@op...> - 2025-10-28 14:06:03
|
cron2 has uploaded a new patch set (#2) to the change originally created by selvanair. ( http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email ) The following approvals got outdated and were removed: Code-Review+2 by plaisthos, Code-Review+2 by stipa Change subject: Canonicalize config_dir before comparing with the config file location ...................................................................... Canonicalize config_dir before comparing with the config file location Found by ZeroPath Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Signed-off-by: Selva Nair <sel...@gm...> Acked-by: Arne Schwabe <arn...@rf...> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1318 Message-Id: <202...@gr...> URL: https://www.mail-archive.com/ope...@li.../msg33923.html Signed-off-by: Gert Doering <ge...@gr...> --- M src/openvpnserv/CMakeLists.txt M src/openvpnserv/validate.c 2 files changed, 17 insertions(+), 4 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/18/1318/2 diff --git a/src/openvpnserv/CMakeLists.txt b/src/openvpnserv/CMakeLists.txt index 340b904..a92ee08 100644 --- a/src/openvpnserv/CMakeLists.txt +++ b/src/openvpnserv/CMakeLists.txt @@ -6,6 +6,11 @@ add_executable(openvpnserv) +include(CheckSymbolExists) + +# Some old versions of mingw does not have PATHCCH_OPTIONS enums -- add a check +check_symbol_exists(PATHCCH_ENSURE_TRAILING_SLASH pathcch.h HAVE_PATHCCH_ENSURE_TRAILING_SLASH) + set(MC_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/mc) target_include_directories(openvpnserv PRIVATE @@ -31,7 +36,7 @@ ) target_link_libraries(openvpnserv advapi32.lib userenv.lib iphlpapi.lib fwpuclnt.lib rpcrt4.lib - shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib) + shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib pathcch.lib) if (MINGW) target_compile_options(openvpnserv PRIVATE -municode) target_link_options(openvpnserv PRIVATE -municode) diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c index 59d5b86..2187fb5 100644 --- a/src/openvpnserv/validate.c +++ b/src/openvpnserv/validate.c @@ -25,6 +25,11 @@ #include <lmaccess.h> #include <shlwapi.h> #include <lm.h> +#include <pathcch.h> + +#ifndef HAVE_PATHCCH_ENSURE_TRAILING_SLASH +#define PATHCCH_ENSURE_TRAILING_SLASH 0x20 +#endif static const WCHAR *white_list[] = { L"auth-retry", @@ -61,7 +66,7 @@ { WCHAR tmp[MAX_PATH]; const WCHAR *config_file = NULL; - const WCHAR *config_dir = NULL; + WCHAR config_dir[MAX_PATH]; /* convert fname to full path */ if (PathIsRelativeW(fname)) @@ -74,9 +79,12 @@ config_file = fname; } - config_dir = s->config_dir; + /* canonicalize config_dir and add trailing slash before comparison */ + HRESULT res = PathCchCanonicalizeEx(config_dir, _countof(config_dir), s->config_dir, + PATHCCH_ENSURE_TRAILING_SLASH); - if (wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0 + if (res == S_OK + && wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0 && wcsstr(config_file + wcslen(config_dir), L"..") == NULL) { return TRUE; -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: newpatchset Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Gerrit-Change-Number: 1318 Gerrit-PatchSet: 2 Gerrit-Owner: selvanair <sel...@gm...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-Reviewer: stipa <lst...@gm...> Gerrit-CC: openvpn-devel <ope...@li...> |
|
From: cron2 (C. Review) <ge...@op...> - 2025-10-28 14:06:09
|
cron2 has submitted this change. ( http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email ) Change subject: Canonicalize config_dir before comparing with the config file location ...................................................................... Canonicalize config_dir before comparing with the config file location Found by ZeroPath Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Signed-off-by: Selva Nair <sel...@gm...> Acked-by: Arne Schwabe <arn...@rf...> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1318 Message-Id: <202...@gr...> URL: https://www.mail-archive.com/ope...@li.../msg33923.html Signed-off-by: Gert Doering <ge...@gr...> --- M src/openvpnserv/CMakeLists.txt M src/openvpnserv/validate.c 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/openvpnserv/CMakeLists.txt b/src/openvpnserv/CMakeLists.txt index 340b904..a92ee08 100644 --- a/src/openvpnserv/CMakeLists.txt +++ b/src/openvpnserv/CMakeLists.txt @@ -6,6 +6,11 @@ add_executable(openvpnserv) +include(CheckSymbolExists) + +# Some old versions of mingw does not have PATHCCH_OPTIONS enums -- add a check +check_symbol_exists(PATHCCH_ENSURE_TRAILING_SLASH pathcch.h HAVE_PATHCCH_ENSURE_TRAILING_SLASH) + set(MC_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/mc) target_include_directories(openvpnserv PRIVATE @@ -31,7 +36,7 @@ ) target_link_libraries(openvpnserv advapi32.lib userenv.lib iphlpapi.lib fwpuclnt.lib rpcrt4.lib - shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib) + shlwapi.lib netapi32.lib ws2_32.lib ntdll.lib ole32.lib pathcch.lib) if (MINGW) target_compile_options(openvpnserv PRIVATE -municode) target_link_options(openvpnserv PRIVATE -municode) diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c index 59d5b86..2187fb5 100644 --- a/src/openvpnserv/validate.c +++ b/src/openvpnserv/validate.c @@ -25,6 +25,11 @@ #include <lmaccess.h> #include <shlwapi.h> #include <lm.h> +#include <pathcch.h> + +#ifndef HAVE_PATHCCH_ENSURE_TRAILING_SLASH +#define PATHCCH_ENSURE_TRAILING_SLASH 0x20 +#endif static const WCHAR *white_list[] = { L"auth-retry", @@ -61,7 +66,7 @@ { WCHAR tmp[MAX_PATH]; const WCHAR *config_file = NULL; - const WCHAR *config_dir = NULL; + WCHAR config_dir[MAX_PATH]; /* convert fname to full path */ if (PathIsRelativeW(fname)) @@ -74,9 +79,12 @@ config_file = fname; } - config_dir = s->config_dir; + /* canonicalize config_dir and add trailing slash before comparison */ + HRESULT res = PathCchCanonicalizeEx(config_dir, _countof(config_dir), s->config_dir, + PATHCCH_ENSURE_TRAILING_SLASH); - if (wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0 + if (res == S_OK + && wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0 && wcsstr(config_file + wcslen(config_dir), L"..") == NULL) { return TRUE; -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1318?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: merged Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I8e884c00cb94f97a612056e8dca74d821a6d6386 Gerrit-Change-Number: 1318 Gerrit-PatchSet: 2 Gerrit-Owner: selvanair <sel...@gm...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-Reviewer: stipa <lst...@gm...> Gerrit-CC: openvpn-devel <ope...@li...> |