diff --git a/base/applications/network/tracert/lang/bg-BG.rc b/base/applications/network/tracert/lang/bg-BG.rc index 33a864cc30b..1fc717f157b 100644 --- a/base/applications/network/tracert/lang/bg-BG.rc +++ b/base/applications/network/tracert/lang/bg-BG.rc @@ -33,4 +33,7 @@ Options:\n\ IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "Destination host unreachable.\n" IDS_DEST_NET_UNREACHABLE "Destination network unreachable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/cs-CZ.rc b/base/applications/network/tracert/lang/cs-CZ.rc index 280af40eae9..37984f94ba7 100644 --- a/base/applications/network/tracert/lang/cs-CZ.rc +++ b/base/applications/network/tracert/lang/cs-CZ.rc @@ -33,4 +33,7 @@ Options:\n\ IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "Destination host unreachable.\n" IDS_DEST_NET_UNREACHABLE "Destination network unreachable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/de-DE.rc b/base/applications/network/tracert/lang/de-DE.rc index 6f078a049fb..46a43335111 100644 --- a/base/applications/network/tracert/lang/de-DE.rc +++ b/base/applications/network/tracert/lang/de-DE.rc @@ -38,4 +38,7 @@ Optionen:\n\ IDS_HOP_RESPONSE " Antwort: " IDS_DEST_HOST_UNREACHABLE "Zielhost nicht erreichbar.\n" IDS_DEST_NET_UNREACHABLE "Zielnetz nicht erreichbar.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/en-US.rc b/base/applications/network/tracert/lang/en-US.rc index ed92f0292f1..54f398e0010 100644 --- a/base/applications/network/tracert/lang/en-US.rc +++ b/base/applications/network/tracert/lang/en-US.rc @@ -33,4 +33,7 @@ Options:\n\ IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "Destination host unreachable.\n" IDS_DEST_NET_UNREACHABLE "Destination network unreachable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/es-ES.rc b/base/applications/network/tracert/lang/es-ES.rc index f0e92862601..d14fed1887c 100644 --- a/base/applications/network/tracert/lang/es-ES.rc +++ b/base/applications/network/tracert/lang/es-ES.rc @@ -33,4 +33,7 @@ Options:\n\ IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "Destination host unreachable.\n" IDS_DEST_NET_UNREACHABLE "Destination network unreachable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/fr-FR.rc b/base/applications/network/tracert/lang/fr-FR.rc index 2123236a317..bec82e8ca1a 100644 --- a/base/applications/network/tracert/lang/fr-FR.rc +++ b/base/applications/network/tracert/lang/fr-FR.rc @@ -33,4 +33,7 @@ Options :\n\ IDS_HOP_RESPONSE " rapporte : " IDS_DEST_HOST_UNREACHABLE "Hôte de destination inatteignable.\n" IDS_DEST_NET_UNREACHABLE "Réseau de destination inatteignable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/it-IT.rc b/base/applications/network/tracert/lang/it-IT.rc index 8729bce5b86..77150570169 100644 --- a/base/applications/network/tracert/lang/it-IT.rc +++ b/base/applications/network/tracert/lang/it-IT.rc @@ -39,4 +39,7 @@ Opzioni:\n\ IDS_HOP_RESPONSE " rapporti: " IDS_DEST_HOST_UNREACHABLE "Destinazione ospite irraggiungibile.\n" IDS_DEST_NET_UNREACHABLE "Destinazione rete irraggiungibile.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/pl-PL.rc b/base/applications/network/tracert/lang/pl-PL.rc index 932622780e4..9711c12def9 100644 --- a/base/applications/network/tracert/lang/pl-PL.rc +++ b/base/applications/network/tracert/lang/pl-PL.rc @@ -33,4 +33,7 @@ Opcje:\n\ IDS_HOP_RESPONSE " raporty: " IDS_DEST_HOST_UNREACHABLE "Host docelowy nieosiągalny.\n" IDS_DEST_NET_UNREACHABLE "Sieć docelowa nieosiągalna.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/ro-RO.rc b/base/applications/network/tracert/lang/ro-RO.rc index a06f9ab24b4..840c497ff5d 100644 --- a/base/applications/network/tracert/lang/ro-RO.rc +++ b/base/applications/network/tracert/lang/ro-RO.rc @@ -39,4 +39,7 @@ Opțiuni:\n\ IDS_HOP_RESPONSE " rapoarte: " IDS_DEST_HOST_UNREACHABLE "Destinație gazdă inaccesibilă.\n" IDS_DEST_NET_UNREACHABLE "Destinație rețea inaccesibilă.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/ru-RU.rc b/base/applications/network/tracert/lang/ru-RU.rc index ddf24e183ed..585e5f0b6f2 100644 --- a/base/applications/network/tracert/lang/ru-RU.rc +++ b/base/applications/network/tracert/lang/ru-RU.rc @@ -34,4 +34,7 @@ BEGIN IDS_HOP_RESPONSE " сообщает: " IDS_DEST_HOST_UNREACHABLE "Заданный узел недоступен.\n" IDS_DEST_NET_UNREACHABLE "Заданная сеть недоступна.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/sq-AL.rc b/base/applications/network/tracert/lang/sq-AL.rc index b3e6137a747..c9263fddae4 100644 --- a/base/applications/network/tracert/lang/sq-AL.rc +++ b/base/applications/network/tracert/lang/sq-AL.rc @@ -33,4 +33,7 @@ Options:\n\ IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "Destination host unreachable.\n" IDS_DEST_NET_UNREACHABLE "Destination network unreachable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/sv-SE.rc b/base/applications/network/tracert/lang/sv-SE.rc index 7ba8238b69b..90376f99984 100644 --- a/base/applications/network/tracert/lang/sv-SE.rc +++ b/base/applications/network/tracert/lang/sv-SE.rc @@ -33,4 +33,7 @@ Options:\n\ IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "Destination host unreachable.\n" IDS_DEST_NET_UNREACHABLE "Destination network unreachable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/tr-TR.rc b/base/applications/network/tracert/lang/tr-TR.rc index fcea8cd947d..61d8a4e775a 100644 --- a/base/applications/network/tracert/lang/tr-TR.rc +++ b/base/applications/network/tracert/lang/tr-TR.rc @@ -34,4 +34,7 @@ Seçenekler:\n\ IDS_HOP_RESPONSE " raporlar: " IDS_DEST_HOST_UNREACHABLE "Hedef cihaza erişilemiyor.\n" IDS_DEST_NET_UNREACHABLE "Hedef ağa erişilemiyor.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/uk-UA.rc b/base/applications/network/tracert/lang/uk-UA.rc index f358564aa09..4181ccafedd 100644 --- a/base/applications/network/tracert/lang/uk-UA.rc +++ b/base/applications/network/tracert/lang/uk-UA.rc @@ -33,4 +33,7 @@ Options:\n\ IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "Destination host unreachable.\n" IDS_DEST_NET_UNREACHABLE "Destination network unreachable.\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/zh-CN.rc b/base/applications/network/tracert/lang/zh-CN.rc index 6178902c150..df9d7f15fcd 100644 --- a/base/applications/network/tracert/lang/zh-CN.rc +++ b/base/applications/network/tracert/lang/zh-CN.rc @@ -33,4 +33,7 @@ BEGIN IDS_HOP_RESPONSE " 报告: " IDS_DEST_HOST_UNREACHABLE "目标主机不可达。\n" IDS_DEST_NET_UNREACHABLE "目标网络不可达。\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/lang/zh-TW.rc b/base/applications/network/tracert/lang/zh-TW.rc index fa1194ae662..5a7abb10283 100644 --- a/base/applications/network/tracert/lang/zh-TW.rc +++ b/base/applications/network/tracert/lang/zh-TW.rc @@ -39,4 +39,7 @@ BEGIN IDS_HOP_RESPONSE " reports: " IDS_DEST_HOST_UNREACHABLE "無法連線至目標主機。\n" IDS_DEST_NET_UNREACHABLE "無法連線至目標網路。\n" + IDS_BAD_OPTION_VALUE "Bad value for option %1!ls!.\n" + IDS_MISSING_OPTION_VALUE "A value must be supplied for option %1!ls!.\n" + IDS_MISSING_TARGET "A target name or address must be specified.\n" END diff --git a/base/applications/network/tracert/resource.h b/base/applications/network/tracert/resource.h index 01f68bbdba6..be4ebc59442 100644 --- a/base/applications/network/tracert/resource.h +++ b/base/applications/network/tracert/resource.h @@ -19,3 +19,6 @@ #define IDS_HOP_RESPONSE 115 #define IDS_DEST_HOST_UNREACHABLE 116 #define IDS_DEST_NET_UNREACHABLE 117 +#define IDS_BAD_OPTION_VALUE 118 +#define IDS_MISSING_OPTION_VALUE 119 +#define IDS_MISSING_TARGET 120 diff --git a/base/applications/network/tracert/tracert.cpp b/base/applications/network/tracert/tracert.cpp index 85b4aeb0908..d51e474ceda 100644 --- a/base/applications/network/tracert/tracert.cpp +++ b/base/applications/network/tracert/tracert.cpp @@ -3,6 +3,7 @@ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Trace network paths through networks * COPYRIGHT: Copyright 2018 Ged Murphy + Copyright 2025 Curtis Wilson */ #ifdef __REACTOS__ @@ -24,6 +25,7 @@ #include #include #include +#include #include "resource.h" #define SIZEOF_ICMP_ERROR 8 @@ -31,6 +33,10 @@ #define PACKET_SIZE 32 #define MAX_IPADDRESS 32 #define NUM_OF_PINGS 3 +#define MIN_HOP_COUNT 1 +#define MAX_HOP_COUNT 255 +#define MIN_MILLISECONDS 1 +#define MAX_MILLISECONDS ULONG_MAX struct TraceInfo { @@ -153,23 +159,29 @@ Usage() OutputText(IDS_USAGE); } -static ULONG +static bool GetULONG( - _In_z_ LPWSTR String + _In_ PWSTR String, + _Out_ ULONG *Value ) { - ULONG Length; - Length = wcslen(String); - - ULONG i = 0; - while ((i < Length) && ((String[i] < L'0') || (String[i] > L'9'))) i++; - if ((i >= Length) || ((String[i] < L'0') || (String[i] > L'9'))) - { - return (ULONG)-1; - } - LPWSTR StopString; - return wcstoul(&String[i], &StopString, 10); + + // check input arguments + if (String == NULL || Value == NULL || *String == UNICODE_NULL) + return false; + + // clear errno so we can use its value + // after the call to wcstoul to check for errors + errno = 0; + + // try to convert String to ULONG + *Value = wcstoul(String, &StopString, 10); + if ((errno != ERANGE) && (errno != 0 || *StopString != UNICODE_NULL)) + return false; + + // the conversion was successful + return true; } static bool @@ -557,6 +569,52 @@ Cleanup: return Success; } +static bool +GetUlongOptionInRange( + _In_ int argc, + _In_ wchar_t *argv[], + _Inout_ int *i, + _Out_ ULONG *Value, + _In_ ULONG MinimumValue, + _In_ ULONG MaximumValue) +{ + ULONG ParsedValue = 0; + + // check input arguments + if (argv == NULL || i == NULL || Value == NULL) + return false; + + // see if we have enough values + if ((*i + 1) > (argc - 1)) + { + OutputText(IDS_MISSING_OPTION_VALUE, argv[*i]); + return false; + } + + (*i)++; + + // try to parse and convert value as ULONG + // check if ParsedValue is within specified range + if (!GetULONG(argv[*i], &ParsedValue) + || ((ParsedValue < MinimumValue) || (ParsedValue > MaximumValue))) + { + // if GetULONG Fails we need to check ERANGE to see if + // it was due to the value being out of range + if (errno == ERANGE) + { + *Value = ParsedValue; + return true; + } + + (*i)--; + OutputText(IDS_BAD_OPTION_VALUE, argv[*i]); + return false; + } + + *Value = ParsedValue; + return true; +} + static bool ParseCmdline(int argc, wchar_t *argv[]) { @@ -568,7 +626,7 @@ ParseCmdline(int argc, wchar_t *argv[]) for (int i = 1; i < argc; i++) { - if (argv[i][0] == '-') + if (argv[i][0] == '-' || argv[i][0] == '/') { switch (argv[i][1]) { @@ -577,7 +635,13 @@ ParseCmdline(int argc, wchar_t *argv[]) break; case 'h': - Info.MaxHops = GetULONG(argv[++i]); + if (!GetUlongOptionInRange(argc, + argv, + &i, + &Info.MaxHops, + MIN_HOP_COUNT, + MAX_HOP_COUNT)) + return false; break; case 'j': @@ -585,7 +649,13 @@ ParseCmdline(int argc, wchar_t *argv[]) return false; case 'w': - Info.Timeout = GetULONG(argv[++i]); + if (!GetUlongOptionInRange(argc, + argv, + &i, + &Info.Timeout, + MIN_MILLISECONDS, + MAX_MILLISECONDS)) + return false; break; case '4': @@ -606,11 +676,26 @@ ParseCmdline(int argc, wchar_t *argv[]) } else { + // the host must be the last argument + if (i != (argc - 1)) + { + Usage(); + return false; + } + StringCchCopyW(Info.HostName, NI_MAXHOST, argv[i]); break; } } + // check for missing host + if (Info.HostName[0] == UNICODE_NULL) + { + OutputText(IDS_MISSING_TARGET); + Usage(); + return false; + } + return true; }