mirror of
https://github.com/moonlight-stream/Internet-Hosting-Tool.git
synced 2025-07-01 23:35:27 +00:00
Fix parsing bug handling empty SSDP headers
This commit is contained in:
parent
2c2f275c3d
commit
3c92a79fe2
102
miss/tracer.cpp
102
miss/tracer.cpp
@ -22,6 +22,55 @@ static const char* k_SsdpSearchFormatString =
|
|||||||
"MX: 5\r\n"
|
"MX: 5\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
|
// Based on logic in https://github.com/miniupnp/miniupnp/blob/master/miniupnpc/minissdpc.c
|
||||||
|
static void
|
||||||
|
parseReply(const char* reply, int size,
|
||||||
|
const char** location, int *locationsize,
|
||||||
|
const char** st, int* stsize,
|
||||||
|
const char** usn, int* usnsize)
|
||||||
|
{
|
||||||
|
int lineStartIdx = 0;
|
||||||
|
int headerEndIdx = 0;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
switch (reply[i])
|
||||||
|
{
|
||||||
|
case ':':
|
||||||
|
// Stop parsing the header at the first colon, but ignore subsequent colons
|
||||||
|
if (headerEndIdx == 0) {
|
||||||
|
headerEndIdx = i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
|
if (headerEndIdx != 0) {
|
||||||
|
// Skip the colon and spaces
|
||||||
|
do { headerEndIdx++; } while (reply[headerEndIdx] == ' ');
|
||||||
|
|
||||||
|
// Check if it's one of the values we care about
|
||||||
|
if (!_strnicmp(reply + lineStartIdx, "location:", 9)) {
|
||||||
|
*location = reply + headerEndIdx;
|
||||||
|
*locationsize = i - headerEndIdx;
|
||||||
|
}
|
||||||
|
else if (!_strnicmp(reply + lineStartIdx, "st:", 3)) {
|
||||||
|
*st = reply + headerEndIdx;
|
||||||
|
*stsize = i - headerEndIdx;
|
||||||
|
}
|
||||||
|
else if (!_strnicmp(reply + lineStartIdx, "usn:", 4)) {
|
||||||
|
*usn = reply + headerEndIdx;
|
||||||
|
*usnsize = i - headerEndIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move on to the next header value
|
||||||
|
headerEndIdx = 0;
|
||||||
|
}
|
||||||
|
lineStartIdx = i + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address)
|
struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address)
|
||||||
{
|
{
|
||||||
SOCKET s;
|
SOCKET s;
|
||||||
@ -122,38 +171,37 @@ struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse the header options
|
// Parse the header options
|
||||||
// SERVER: FreeBSD/11.2-RELEASE-p2 UPnP/1.1 MiniUPnPd/2.0\r\n
|
char* remainder = strtok(nullptr, "");
|
||||||
char* location = nullptr;
|
const char* loc = nullptr;
|
||||||
char* st = nullptr;
|
const char* st = nullptr;
|
||||||
while (char* headerName = strtok(nullptr, "\r\n:")) {
|
const char* usn = ""; // Initialize to empty since it's optional
|
||||||
char* headerValue = strtok(nullptr, "\r");
|
int locSize = 0;
|
||||||
if (headerValue == nullptr) {
|
int stSize = 0;
|
||||||
printf("Unexpected end of SSDP header\n");
|
int usnSize = 0;
|
||||||
break;
|
parseReply(remainder, strlen(remainder),
|
||||||
}
|
&loc, &locSize, &st, &stSize, &usn, &usnSize);
|
||||||
|
|
||||||
// Skip leading spaces
|
if (!loc || locSize == 0 || !st || stSize == 0) {
|
||||||
while (*headerValue == ' ') headerValue++;
|
printf("Required value missing: %d %d\n", locSize, stSize);
|
||||||
|
|
||||||
if (!_stricmp(headerName, "LOCATION")) {
|
|
||||||
location = headerValue;
|
|
||||||
}
|
|
||||||
else if (!_stricmp(headerName, "ST")) {
|
|
||||||
st = headerValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!location || location[0] == 0 || !st || st[0] == 0) {
|
|
||||||
printf("Required value missing: \"%s\" \"%s\"\n", location, st);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UPNPDev* newDev = (struct UPNPDev*)malloc(sizeof(*newDev) + strlen(location) + strlen(st) + 2);
|
struct UPNPDev* newDev = (struct UPNPDev*)malloc(sizeof(*newDev) + usnSize + locSize + stSize + 3);
|
||||||
|
|
||||||
newDev->pNext = deviceList;
|
newDev->pNext = deviceList;
|
||||||
newDev->usn = &newDev->buffer[0]; newDev->buffer[0] = 0;
|
|
||||||
newDev->descURL = strcpy(newDev->usn + strlen(newDev->usn) + 1, location);
|
newDev->usn = &newDev->buffer[0];
|
||||||
newDev->st = strcpy(newDev->descURL + strlen(newDev->descURL) + 1, st);
|
memcpy(newDev->usn, usn, usnSize);
|
||||||
|
newDev->usn[usnSize] = 0;
|
||||||
|
|
||||||
|
newDev->descURL = newDev->usn + usnSize + 1;
|
||||||
|
memcpy(newDev->descURL, loc, locSize);
|
||||||
|
newDev->descURL[locSize] = 0;
|
||||||
|
|
||||||
|
newDev->st = newDev->descURL + locSize + 1;
|
||||||
|
memcpy(newDev->st, st, stSize);
|
||||||
|
newDev->st[stSize] = 0;
|
||||||
|
|
||||||
newDev->scope_id = 0; // IPv6 only
|
newDev->scope_id = 0; // IPv6 only
|
||||||
|
|
||||||
deviceList = newDev;
|
deviceList = newDev;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user