Use safe string functions in C11

This commit is contained in:
Cameron Gutman 2020-11-30 21:45:57 -06:00
parent 4b4162c1a1
commit 04dc3c52f6
8 changed files with 72 additions and 58 deletions

View File

@ -39,6 +39,10 @@ extern int AudioPacketDuration;
#define isBefore24(x, y) (U24((x) - (y)) > (UINT24_MAX/2))
#define isBefore32(x, y) (U32((x) - (y)) > (UINT32_MAX/2))
#ifndef ARRAYSIZE
#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
#endif
#define UDP_RECV_POLL_TIMEOUT_MS 100
// At this value or above, we will request high quality audio unless CAPABILITY_SLOW_OPUS_DECODER

View File

@ -37,7 +37,7 @@ int extractVersionQuadFromString(const char* string, int* quad) {
char* nextNumber;
int i;
strcpy(versionString, string);
strcpy_s(versionString, ARRAYSIZE(versionString), string);
nextNumber = versionString;
for (i = 0; i < 4; i++) {

View File

@ -1,5 +1,8 @@
#pragma once
// Don't warn for POSIX functions like strdup
#define _CRT_NONSTDC_NO_DEPRECATE
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

View File

@ -30,14 +30,14 @@ void addrToUrlSafeString(struct sockaddr_storage* addr, char* string)
inet_ntop(addr->ss_family, &sin6->sin6_addr, addrstr, sizeof(addrstr));
// IPv6 addresses need to be enclosed in brackets for URLs
sprintf(string, "[%s]", addrstr);
sprintf_s(string, URLSAFESTRING_LEN, "[%s]", addrstr);
}
else {
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
inet_ntop(addr->ss_family, &sin->sin_addr, addrstr, sizeof(addrstr));
// IPv4 addresses are returned without changes
sprintf(string, "%s", addrstr);
sprintf_s(string, URLSAFESTRING_LEN, "%s", addrstr);
}
}

View File

@ -71,8 +71,8 @@ static bool initializeRtspRequest(PRTSP_MESSAGE msg, char* command, char* target
createRtspRequest(msg, NULL, 0, command, target, "RTSP/1.0",
0, NULL, NULL, 0);
sprintf(sequenceNumberStr, "%d", currentSeqNumber++);
sprintf(clientVersionStr, "%d", rtspClientVersion);
sprintf_s(sequenceNumberStr, ARRAYSIZE(sequenceNumberStr), "%d", currentSeqNumber++);
sprintf_s(clientVersionStr, ARRAYSIZE(clientVersionStr), "%d", rtspClientVersion);
if (!addOption(msg, "CSeq", sequenceNumberStr) ||
!addOption(msg, "X-GS-ClientVersion", clientVersionStr) ||
(!useEnet && !addOption(msg, "Host", urlAddr))) {
@ -434,7 +434,7 @@ static bool sendVideoAnnounce(PRTSP_MESSAGE response, int* error) {
request.flags |= FLAG_ALLOCATED_PAYLOAD;
request.payloadLength = payloadLength;
sprintf(payloadLengthStr, "%d", payloadLength);
sprintf_s(payloadLengthStr, ARRAYSIZE(payloadLengthStr), "%d", payloadLength);
if (!addOption(&request, "Content-length", payloadLengthStr)) {
goto FreeMessage;
}
@ -508,7 +508,7 @@ static int parseOpusConfigurations(PRTSP_MESSAGE response) {
channelCount = CHANNEL_COUNT_FROM_AUDIO_CONFIGURATION(StreamConfig.audioConfiguration);
// Find the correct audio parameter value
sprintf(paramsPrefix, "a=fmtp:97 surround-params=%d", channelCount);
sprintf_s(paramsPrefix, ARRAYSIZE(paramsPrefix), "a=fmtp:97 surround-params=%d", channelCount);
paramStart = strstr(response->payload, paramsPrefix);
if (paramStart) {
// Skip the prefix
@ -596,12 +596,12 @@ int performRtspHandshake(void) {
addrToUrlSafeString(&RemoteAddr, urlAddr);
}
else {
strcpy(urlAddr, "0.0.0.0");
strcpy_s(urlAddr, ARRAYSIZE(urlAddr), "0.0.0.0");
}
// Initialize global state
useEnet = (AppVersionQuad[0] >= 5) && (AppVersionQuad[0] <= 7) && (AppVersionQuad[2] < 404);
sprintf(rtspTargetUrl, "rtsp%s://%s:48010", useEnet ? "ru" : "", urlAddr);
sprintf_s(rtspTargetUrl, ARRAYSIZE(rtspTargetUrl), "rtsp%s://%s:48010", useEnet ? "ru" : "", urlAddr);
currentSeqNumber = 1;
hasSessionId = false;
@ -740,6 +740,7 @@ int performRtspHandshake(void) {
{
RTSP_MESSAGE response;
char* sessionId;
char* tokenizerContext;
int error = -1;
if (!setupStream(&response,
@ -770,7 +771,7 @@ int performRtspHandshake(void) {
// resolves any 454 session not found errors on
// standard RTSP server implementations.
// (i.e - sessionId = "DEADBEEFCAFE;timeout = 90")
sessionIdString = strdup(strtok(sessionId, ";"));
sessionIdString = strdup(strtok_s(sessionId, ";", &tokenizerContext));
if (sessionIdString == NULL) {
Limelog("Failed to duplicate session ID string\n");
ret = -1;

View File

@ -1,3 +1,4 @@
#include "Limelight-internal.h"
#include "Rtsp.h"
// Check if String s begins with the given prefix
@ -26,7 +27,7 @@ static int getMessageLength(PRTSP_MESSAGE msg) {
// Add length of response-specific strings
else {
char statusCodeStr[16];
sprintf(statusCodeStr, "%d", msg->message.response.statusCode);
sprintf_s(statusCodeStr, ARRAYSIZE(statusCodeStr), "%d", msg->message.response.statusCode);
count += strlen(statusCodeStr);
count += strlen(msg->message.response.statusString);
// two spaces and \r\n
@ -53,6 +54,7 @@ static int getMessageLength(PRTSP_MESSAGE msg) {
// Given an RTSP message string rtspMessage, parse it into an RTSP_MESSAGE struct msg
int parseRtspMessage(PRTSP_MESSAGE msg, char* rtspMessage, int length) {
char* token;
char* tokenizerContext;
char* protocol;
char* endCheck;
char* target;
@ -88,7 +90,7 @@ int parseRtspMessage(PRTSP_MESSAGE msg, char* rtspMessage, int length) {
messageBuffer[length] = 0;
// Get the first token of the message
token = strtok(messageBuffer, delim);
token = strtok_s(messageBuffer, delim, &tokenizerContext);
if (token == NULL) {
exitCode = RTSP_ERROR_MALFORMED;
goto ExitFailure;
@ -101,7 +103,7 @@ int parseRtspMessage(PRTSP_MESSAGE msg, char* rtspMessage, int length) {
protocol = token;
// Get the status code
token = strtok(NULL, delim);
token = strtok_s(NULL, delim, &tokenizerContext);
statusCode = atoi(token);
if (token == NULL) {
exitCode = RTSP_ERROR_MALFORMED;
@ -109,7 +111,7 @@ int parseRtspMessage(PRTSP_MESSAGE msg, char* rtspMessage, int length) {
}
// Get the status string
statusStr = strtok(NULL, end);
statusStr = strtok_s(NULL, end, &tokenizerContext);
if (statusStr == NULL) {
exitCode = RTSP_ERROR_MALFORMED;
goto ExitFailure;
@ -124,12 +126,12 @@ int parseRtspMessage(PRTSP_MESSAGE msg, char* rtspMessage, int length) {
else {
flag = TYPE_REQUEST;
command = token;
target = strtok(NULL, delim);
target = strtok_s(NULL, delim, &tokenizerContext);
if (target == NULL) {
exitCode = RTSP_ERROR_MALFORMED;
goto ExitFailure;
}
protocol = strtok(NULL, delim);
protocol = strtok_s(NULL, delim, &tokenizerContext);
if (protocol == NULL) {
exitCode = RTSP_ERROR_MALFORMED;
goto ExitFailure;
@ -144,7 +146,7 @@ int parseRtspMessage(PRTSP_MESSAGE msg, char* rtspMessage, int length) {
// Parse remaining options
while (token != NULL)
{
token = strtok(NULL, typeFlag == TOKEN_OPTION ? optDelim : end);
token = strtok_s(NULL, typeFlag == TOKEN_OPTION ? optDelim : end, &tokenizerContext);
if (token != NULL) {
if (typeFlag == TOKEN_OPTION) {
opt = token;
@ -322,37 +324,37 @@ char* serializeRtspMessage(PRTSP_MESSAGE msg, int* serializedLength) {
if (msg->type == TYPE_REQUEST) {
// command [space]
strcpy(serializedMessage, msg->message.request.command);
strcat(serializedMessage, " ");
strcpy_s(serializedMessage, size, msg->message.request.command);
strcat_s(serializedMessage, size, " ");
// target [space]
strcat(serializedMessage, msg->message.request.target);
strcat(serializedMessage, " ");
strcat_s(serializedMessage, size, msg->message.request.target);
strcat_s(serializedMessage, size, " ");
// protocol \r\n
strcat(serializedMessage, msg->protocol);
strcat(serializedMessage, "\r\n");
strcat_s(serializedMessage, size, msg->protocol);
strcat_s(serializedMessage, size, "\r\n");
}
else {
// protocol [space]
strcpy(serializedMessage, msg->protocol);
strcat(serializedMessage, " ");
strcpy_s(serializedMessage, size, msg->protocol);
strcat_s(serializedMessage, size, " ");
// status code [space]
sprintf(statusCodeStr, "%d", msg->message.response.statusCode);
strcat(serializedMessage, statusCodeStr);
strcat(serializedMessage, " ");
sprintf_s(statusCodeStr, ARRAYSIZE(statusCodeStr), "%d", msg->message.response.statusCode);
strcat_s(serializedMessage, size, statusCodeStr);
strcat_s(serializedMessage, size, " ");
// status str\r\n
strcat(serializedMessage, msg->message.response.statusString);
strcat(serializedMessage, "\r\n");
strcat_s(serializedMessage, size, msg->message.response.statusString);
strcat_s(serializedMessage, size, "\r\n");
}
// option content\r\n
while (current != NULL) {
strcat(serializedMessage, current->option);
strcat(serializedMessage, ": ");
strcat(serializedMessage, current->content);
strcat(serializedMessage, "\r\n");
strcat_s(serializedMessage, size, current->option);
strcat_s(serializedMessage, size, ": ");
strcat_s(serializedMessage, size, current->content);
strcat_s(serializedMessage, size, "\r\n");
current = current->next;
}
// Final \r\n
strcat(serializedMessage, "\r\n");
strcat_s(serializedMessage, size, "\r\n");
// payload
if (msg->payload != NULL) {

View File

@ -39,14 +39,14 @@ static int getSerializedAttributeListSize(PSDP_OPTION head) {
}
// Populate the serialized attribute list into a string
static int fillSerializedAttributeList(char* buffer, PSDP_OPTION head) {
static int fillSerializedAttributeList(char* buffer, int bufferLength, PSDP_OPTION head) {
PSDP_OPTION currentEntry = head;
int offset = 0;
while (currentEntry != NULL) {
offset += sprintf(&buffer[offset], "a=%s:", currentEntry->name);
offset += sprintf_s(&buffer[offset], bufferLength - offset, "a=%s:", currentEntry->name);
memcpy(&buffer[offset], currentEntry->payload, currentEntry->payloadLen);
offset += currentEntry->payloadLen;
offset += sprintf(&buffer[offset], " \r\n");
offset += sprintf_s(&buffer[offset], bufferLength - offset, " \r\n");
currentEntry = currentEntry->next;
}
@ -64,7 +64,7 @@ static int addAttributeBinary(PSDP_OPTION* head, char* name, const void* payload
option->next = NULL;
option->payloadLen = payloadLen;
strcpy(option->name, name);
strcpy_s(option->name, ARRAYSIZE(option->name), name);
option->payload = (void*)(option + 1);
memcpy(option->payload, payload, payloadLen);
@ -133,7 +133,7 @@ static int addGen4Options(PSDP_OPTION* head, char* addrStr) {
char payloadStr[92];
int err = 0;
sprintf(payloadStr, "rtsp://%s:48010", addrStr);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "rtsp://%s:48010", addrStr);
err |= addAttributeString(head, "x-nv-general.serverAddress", payloadStr);
return err;
@ -175,15 +175,15 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
optionHead = NULL;
err = 0;
sprintf(payloadStr, "%d", StreamConfig.width);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", StreamConfig.width);
err |= addAttributeString(&optionHead, "x-nv-video[0].clientViewportWd", payloadStr);
sprintf(payloadStr, "%d", StreamConfig.height);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", StreamConfig.height);
err |= addAttributeString(&optionHead, "x-nv-video[0].clientViewportHt", payloadStr);
sprintf(payloadStr, "%d", StreamConfig.fps);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", StreamConfig.fps);
err |= addAttributeString(&optionHead, "x-nv-video[0].maxFPS", payloadStr);
sprintf(payloadStr, "%d", StreamConfig.packetSize);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", StreamConfig.packetSize);
err |= addAttributeString(&optionHead, "x-nv-video[0].packetSize", payloadStr);
err |= addAttributeString(&optionHead, "x-nv-video[0].rateControlMode", "4");
@ -222,7 +222,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
// settle on the optimal bitrate if it's somewhere in the middle), so we'll just latch the bitrate
// to the requested value.
if (AppVersionQuad[0] >= 5) {
sprintf(payloadStr, "%d", bitrate);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", bitrate);
err |= addAttributeString(&optionHead, "x-nv-video[0].initialBitrateKbps", payloadStr);
err |= addAttributeString(&optionHead, "x-nv-video[0].initialPeakBitrateKbps", payloadStr);
@ -236,7 +236,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
err |= addAttributeString(&optionHead, "x-nv-video[0].peakBitrate", "4");
}
sprintf(payloadStr, "%d", bitrate);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", bitrate);
err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.minimumBitrate", payloadStr);
err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.maximumBitrate", payloadStr);
}
@ -286,7 +286,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
// If not using slicing, we request 1 slice per frame
slicesPerFrame = 1;
}
sprintf(payloadStr, "%d", slicesPerFrame);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", slicesPerFrame);
err |= addAttributeString(&optionHead, "x-nv-video[0].videoEncoderSlicesPerFrame", payloadStr);
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
@ -340,13 +340,13 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
err |= addAttributeString(&optionHead, "x-nv-video[0].maxNumReferenceFrames", "1");
}
sprintf(payloadStr, "%d", StreamConfig.clientRefreshRateX100);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", StreamConfig.clientRefreshRateX100);
err |= addAttributeString(&optionHead, "x-nv-video[0].clientRefreshRateX100", payloadStr);
}
sprintf(payloadStr, "%d", audioChannelCount);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", audioChannelCount);
err |= addAttributeString(&optionHead, "x-nv-audio.surround.numChannels", payloadStr);
sprintf(payloadStr, "%d", audioChannelMask);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", audioChannelMask);
err |= addAttributeString(&optionHead, "x-nv-audio.surround.channelMask", payloadStr);
if (audioChannelCount > 2) {
err |= addAttributeString(&optionHead, "x-nv-audio.surround.enable", "1");
@ -389,7 +389,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
}
}
sprintf(payloadStr, "%d", AudioPacketDuration);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", AudioPacketDuration);
err |= addAttributeString(&optionHead, "x-nv-aqos.packetDuration", payloadStr);
}
else {
@ -401,7 +401,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
}
if (AppVersionQuad[0] >= 7) {
sprintf(payloadStr, "%d", (StreamConfig.colorSpace << 1) | StreamConfig.colorRange);
sprintf_s(payloadStr, ARRAYSIZE(payloadStr), "%d", (StreamConfig.colorSpace << 1) | StreamConfig.colorRange);
err |= addAttributeString(&optionHead, "x-nv-video[0].encoderCscMode", payloadStr);
}
@ -415,7 +415,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
// Populate the SDP header with required information
static int fillSdpHeader(char* buffer, int rtspClientVersion, char*urlSafeAddr) {
return sprintf(buffer,
return sprintf_s(buffer, MAX_SDP_HEADER_LEN,
"v=0\r\n"
"o=android 0 %d IN %s %s\r\n"
"s=NVIDIA Streaming Client\r\n",
@ -426,7 +426,7 @@ static int fillSdpHeader(char* buffer, int rtspClientVersion, char*urlSafeAddr)
// Populate the SDP tail with required information
static int fillSdpTail(char* buffer) {
return sprintf(buffer,
return sprintf_s(buffer, MAX_SDP_TAIL_LEN,
"t=0 0\r\n"
"m=video %d \r\n",
AppVersionQuad[0] < 4 ? 47996 : 47998);
@ -435,6 +435,7 @@ static int fillSdpTail(char* buffer) {
// Get the SDP attributes for the stream config
char* getSdpPayloadForStreamConfig(int rtspClientVersion, int* length) {
PSDP_OPTION attributeList;
int attributeListSize;
int offset;
char* payload;
char urlSafeAddr[URLSAFESTRING_LEN];
@ -446,15 +447,18 @@ char* getSdpPayloadForStreamConfig(int rtspClientVersion, int* length) {
return NULL;
}
payload = malloc(MAX_SDP_HEADER_LEN + MAX_SDP_TAIL_LEN +
getSerializedAttributeListSize(attributeList));
attributeListSize = getSerializedAttributeListSize(attributeList);
payload = malloc(MAX_SDP_HEADER_LEN + MAX_SDP_TAIL_LEN + attributeListSize);
if (payload == NULL) {
freeAttributeList(attributeList);
return NULL;
}
offset = fillSdpHeader(payload, rtspClientVersion, urlSafeAddr);
offset += fillSerializedAttributeList(&payload[offset], attributeList);
// Add 1 for the null terminator (which will immediately be overwritten by fillSdpTail())
offset += fillSerializedAttributeList(&payload[offset], attributeListSize + 1, attributeList);
offset += fillSdpTail(&payload[offset]);
freeAttributeList(attributeList);

View File

@ -67,7 +67,7 @@ int LiFindExternalAddressIP4(const char* stunServer, unsigned short stunPort, un
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_ADDRCONFIG;
sprintf(stunPortStr, "%u", stunPort);
sprintf_s(stunPortStr, ARRAYSIZE(stunPortStr), "%u", stunPort);
err = getaddrinfo(stunServer, stunPortStr, &hints, &stunAddrs);
if (err != 0 || stunAddrs == NULL) {
Limelog("Failed to resolve STUN server: %d\n", err);