Fixed file name pattern checks in freerdp_channels_list_dynamic_addins

Reported by George Zaytsev from Positive Technologies
This commit is contained in:
akallabeth
2021-12-22 09:04:04 +01:00
committed by akallabeth
parent 7c9117cf86
commit b4d28ab569

View File

@@ -24,6 +24,7 @@
#endif
#include <winpr/crt.h>
#include <winpr/assert.h>
#include <winpr/path.h>
#include <winpr/string.h>
#include <winpr/file.h>
@@ -230,10 +231,8 @@ static FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPCSTR pszName, LPCS
do
{
char* p[5];
FREERDP_ADDIN* pAddin;
nDashes = 0;
pAddin = (FREERDP_ADDIN*)calloc(1, sizeof(FREERDP_ADDIN));
BOOL used = FALSE;
FREERDP_ADDIN* pAddin = (FREERDP_ADDIN*)calloc(1, sizeof(FREERDP_ADDIN));
if (!pAddin)
{
@@ -241,57 +240,140 @@ static FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPCSTR pszName, LPCS
goto error_out;
}
nDashes = 0;
for (index = 0; FindData.cFileName[index]; index++)
nDashes += (FindData.cFileName[index] == '-') ? 1 : 0;
if (nDashes == 1)
{
size_t len;
char* p[2] = { 0 };
/* <name>-client.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
strncpy(pAddin->cName, p[0], (size_t)((p[1] - p[0]) - 1));
p[1] = strchr(p[0], '-');
if (!p[1])
goto skip;
p[1] += 1;
len = (size_t)(p[1] - p[0]);
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cName, p[0], MIN(ARRAYSIZE(pAddin->cName), len - 1));
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
ppAddins[nAddins++] = pAddin;
used = TRUE;
}
else if (nDashes == 2)
{
size_t len;
char* p[4] = { 0 };
/* <name>-client-<subsystem>.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
p[2] = strchr(p[1], '-') + 1;
p[3] = strchr(p[2], '.') + 1;
strncpy(pAddin->cName, p[0], (size_t)((p[1] - p[0]) - 1));
strncpy(pAddin->cSubsystem, p[2], (size_t)((p[3] - p[2]) - 1));
p[1] = strchr(p[0], '-');
if (!p[1])
goto skip;
p[1] += 1;
p[2] = strchr(p[1], '-');
if (!p[2])
goto skip;
p[2] += 1;
p[3] = strchr(p[2], '.');
if (!p[3])
goto skip;
p[3] += 1;
len = (size_t)(p[1] - p[0]);
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cName, p[0], MIN(ARRAYSIZE(pAddin->cName), len - 1));
len = (size_t)(p[3] - p[2]);
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cSubsystem, p[2], MIN(ARRAYSIZE(pAddin->cSubsystem), len - 1));
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
ppAddins[nAddins++] = pAddin;
used = TRUE;
}
else if (nDashes == 3)
{
size_t len;
char* p[5] = { 0 };
/* <name>-client-<subsystem>-<type>.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
p[2] = strchr(p[1], '-') + 1;
p[3] = strchr(p[2], '-') + 1;
p[4] = strchr(p[3], '.') + 1;
strncpy(pAddin->cName, p[0], (size_t)((p[1] - p[0]) - 1));
strncpy(pAddin->cSubsystem, p[2], (size_t)((p[3] - p[2]) - 1));
strncpy(pAddin->cType, p[3], (size_t)((p[4] - p[3]) - 1));
p[1] = strchr(p[0], '-');
if (!p[1])
goto skip;
p[1] += 1;
p[2] = strchr(p[1], '-');
if (!p[2])
goto skip;
p[2] += 1;
p[3] = strchr(p[2], '-');
if (!p[3])
goto skip;
p[3] += 1;
p[4] = strchr(p[3], '.');
if (!p[4])
goto skip;
p[4] += 1;
len = (size_t)(p[1] - p[0]);
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cName, p[0], MIN(ARRAYSIZE(pAddin->cName), len - 1));
len = (size_t)(p[3] - p[2]);
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cSubsystem, p[2], MIN(ARRAYSIZE(pAddin->cSubsystem), len - 1));
len = (size_t)(p[4] - p[3]);
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cType, p[3], MIN(ARRAYSIZE(pAddin->cType), len - 1));
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
pAddin->dwFlags |= FREERDP_ADDIN_TYPE;
ppAddins[nAddins++] = pAddin;
used = TRUE;
}
else
{
skip:
if (!used)
free(pAddin);
}
} while (FindNextFileA(hFind, &FindData));
FindClose(hFind);