diff --git a/src/AudioStream.c b/src/AudioStream.c index ee8da1ce..7ac9658d 100644 --- a/src/AudioStream.c +++ b/src/AudioStream.c @@ -197,14 +197,14 @@ static void decodeInputData(PQUEUED_AUDIO_PACKET packet) { (unsigned char*)(rtp + 1), dataLength, decryptedOpusData, &dataLength)) { Limelog("Failed to decrypt audio packet (sequence number: %u)\n", rtp->sequenceNumber); - LC_ASSERT(false); + LC_ASSERT_VT(false); return; } #ifdef LC_DEBUG if (opusHeaderByte == INVALID_OPUS_HEADER) { opusHeaderByte = decryptedOpusData[0]; - LC_ASSERT(opusHeaderByte != INVALID_OPUS_HEADER); + LC_ASSERT_VT(opusHeaderByte != INVALID_OPUS_HEADER); } else { // Opus header should stay constant for the entire stream. @@ -212,7 +212,7 @@ static void decodeInputData(PQUEUED_AUDIO_PACKET packet) { // incorrectly recovered a data shard or the decryption // of the audio packet failed. Sunshine violates this for // surround sound in some cases, so just ignore it. - LC_ASSERT(decryptedOpusData[0] == opusHeaderByte || IS_SUNSHINE()); + LC_ASSERT_VT(decryptedOpusData[0] == opusHeaderByte || IS_SUNSHINE()); } #endif @@ -222,13 +222,13 @@ static void decodeInputData(PQUEUED_AUDIO_PACKET packet) { #ifdef LC_DEBUG if (opusHeaderByte == INVALID_OPUS_HEADER) { opusHeaderByte = ((uint8_t*)(rtp + 1))[0]; - LC_ASSERT(opusHeaderByte != INVALID_OPUS_HEADER); + LC_ASSERT_VT(opusHeaderByte != INVALID_OPUS_HEADER); } else { // Opus header should stay constant for the entire stream. // If it doesn't, it may indicate that the RtpAudioQueue // incorrectly recovered a data shard. - LC_ASSERT(((uint8_t*)(rtp + 1))[0] == opusHeaderByte); + LC_ASSERT_VT(((uint8_t*)(rtp + 1))[0] == opusHeaderByte); } #endif diff --git a/src/ControlStream.c b/src/ControlStream.c index fc6a7aab..2165d2c1 100644 --- a/src/ControlStream.c +++ b/src/ControlStream.c @@ -425,7 +425,7 @@ void connectionSendFrameFecStatus(PSS_FRAME_FEC_STATUS fecStatus) { } void connectionSawFrame(int frameIndex) { - LC_ASSERT(!isBefore16(frameIndex, lastSeenFrame)); + LC_ASSERT_VT(!isBefore16(frameIndex, lastSeenFrame)); uint64_t now = PltGetMillis(); @@ -1123,7 +1123,7 @@ static void controlReceiveThreadFunc(void* context) { } else { // What do we do here??? - LC_ASSERT(false); + LC_ASSERT_VT(false); packetLength = (int)event.packet->dataLength; event.packet->data = NULL; } diff --git a/src/Platform.h b/src/Platform.h index 9131328f..5978fa2e 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -86,6 +86,17 @@ #define LC_ASSERT(x) assert(x) #endif +// If we're fuzzing, we don't want to enable asserts that can be affected by +// bad input from the remote host. LC_ASSERT_VT() is used for assertions that +// check data that comes from the host. These checks are enabled for normal +// debug builds, since they indicate an error in Moonlight or on the host. +// These are disabled when fuzzing, since the traffic is intentionally invalid. +#ifdef LC_FUZZING +#define LC_ASSERT_VT(x) +#else +#define LC_ASSERT_VT(x) LC_ASSERT(x) +#endif + #ifdef _MSC_VER #pragma intrinsic(_byteswap_ushort) #define BSWAP16(x) _byteswap_ushort(x) diff --git a/src/RtpAudioQueue.c b/src/RtpAudioQueue.c index bc522cb6..be734d4e 100644 --- a/src/RtpAudioQueue.c +++ b/src/RtpAudioQueue.c @@ -1,6 +1,6 @@ #include "Limelight-internal.h" -#ifdef LC_DEBUG +#if defined(LC_DEBUG) && !defined(LC_FUZZING) // This enables FEC validation mode with a synthetic drop // and recovered packet checks vs the original input. It // is on by default for debug builds. @@ -86,12 +86,12 @@ static void validateFecBlockState(PRTP_AUDIO_QUEUE queue) { while (block != NULL) { // Ensure the list is sorted correctly LC_ASSERT(isBefore16(lastSeqNum, block->fecHeader.baseSequenceNumber)); - LC_ASSERT(isBefore32(lastTs, block->fecHeader.baseTimestamp)); + LC_ASSERT_VT(isBefore32(lastTs, block->fecHeader.baseTimestamp)); // Ensure entry invariants are satisfied - LC_ASSERT(block->blockSize == lastBlock->blockSize); - LC_ASSERT(block->fecHeader.payloadType == lastBlock->fecHeader.payloadType); - LC_ASSERT(block->fecHeader.ssrc == lastBlock->fecHeader.ssrc); + LC_ASSERT_VT(block->blockSize == lastBlock->blockSize); + LC_ASSERT_VT(block->fecHeader.payloadType == lastBlock->fecHeader.payloadType); + LC_ASSERT_VT(block->fecHeader.ssrc == lastBlock->fecHeader.ssrc); // Ensure the list itself is consistent LC_ASSERT(block->prev == lastBlock); @@ -205,7 +205,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK if (packet->packetType == RTP_PAYLOAD_TYPE_AUDIO) { if (length < sizeof(RTP_PACKET)) { Limelog("RTP audio data packet too small: %u\n", length); - LC_ASSERT(false); + LC_ASSERT_VT(false); return NULL; } @@ -239,7 +239,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK if (length < sizeof(RTP_PACKET) + sizeof(AUDIO_FEC_HEADER)) { Limelog("RTP audio FEC packet too small: %u\n", length); - LC_ASSERT(false); + LC_ASSERT_VT(false); return NULL; } @@ -253,7 +253,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK // later during recovery. if (fecHeader->fecShardIndex >= RTPA_FEC_SHARDS) { Limelog("Too many audio FEC shards: %u\n", fecHeader->fecShardIndex); - LC_ASSERT(false); + LC_ASSERT_VT(false); return NULL; } @@ -264,7 +264,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK Limelog("Invalid FEC block base sequence number (got %u, expected %u)\n", fecBlockBaseSeqNum, (fecBlockBaseSeqNum / RTPA_DATA_SHARDS) * RTPA_DATA_SHARDS); Limelog("Audio FEC has been disabled due to an incompatibility with your host's old software!\n"); - LC_ASSERT(fecBlockBaseSeqNum % RTPA_DATA_SHARDS == 0); + LC_ASSERT_VT(fecBlockBaseSeqNum % RTPA_DATA_SHARDS == 0); queue->incompatibleServer = true; return NULL; } @@ -273,7 +273,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK } else { Limelog("Invalid RTP audio payload type: %u\n", packet->packetType); - LC_ASSERT(false); + LC_ASSERT_VT(false); return NULL; } @@ -296,9 +296,9 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK while (existingBlock != NULL) { if (existingBlock->fecHeader.baseSequenceNumber == fecBlockBaseSeqNum) { // The FEC header data should match for all packets - LC_ASSERT(existingBlock->fecHeader.payloadType == fecBlockPayloadType); - LC_ASSERT(existingBlock->fecHeader.baseTimestamp == fecBlockBaseTs); - LC_ASSERT(existingBlock->fecHeader.ssrc == fecBlockSsrc); + LC_ASSERT_VT(existingBlock->fecHeader.payloadType == fecBlockPayloadType); + LC_ASSERT_VT(existingBlock->fecHeader.baseTimestamp == fecBlockBaseTs); + LC_ASSERT_VT(existingBlock->fecHeader.ssrc == fecBlockSsrc); // The block size must match in order to safely copy shards into it if (existingBlock->blockSize != blockSize) { @@ -306,7 +306,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK // constant size for audio packets. Limelog("Audio block size mismatch (got %u, expected %u)\n", blockSize, existingBlock->blockSize); Limelog("Audio FEC has been disabled due to an incompatibility with your host's old software!\n"); - LC_ASSERT(existingBlock->blockSize == blockSize); + LC_ASSERT_VT(existingBlock->blockSize == blockSize); queue->incompatibleServer = true; return NULL; } @@ -464,11 +464,11 @@ static bool completeFecBlock(PRTP_AUDIO_QUEUE queue, PRTPA_FEC_BLOCK block) { #ifdef FEC_VALIDATION_MODE // Check the RTP header values - LC_ASSERT(block->dataPackets[dropIndex]->header == droppedRtpPacket->header); - LC_ASSERT(block->dataPackets[dropIndex]->packetType == droppedRtpPacket->packetType); - LC_ASSERT(block->dataPackets[dropIndex]->sequenceNumber == droppedRtpPacket->sequenceNumber); - LC_ASSERT(block->dataPackets[dropIndex]->timestamp == droppedRtpPacket->timestamp); - LC_ASSERT(block->dataPackets[dropIndex]->ssrc == droppedRtpPacket->ssrc); + LC_ASSERT_VT(block->dataPackets[dropIndex]->header == droppedRtpPacket->header); + LC_ASSERT_VT(block->dataPackets[dropIndex]->packetType == droppedRtpPacket->packetType); + LC_ASSERT_VT(block->dataPackets[dropIndex]->sequenceNumber == droppedRtpPacket->sequenceNumber); + LC_ASSERT_VT(block->dataPackets[dropIndex]->timestamp == droppedRtpPacket->timestamp); + LC_ASSERT_VT(block->dataPackets[dropIndex]->ssrc == droppedRtpPacket->ssrc); // Check the data itself - use memcmp() and only loop if an error is detected if (memcmp(block->dataPackets[dropIndex] + 1, droppedRtpPacket + 1, block->blockSize)) { @@ -484,7 +484,7 @@ static bool completeFecBlock(PRTP_AUDIO_QUEUE queue, PRTPA_FEC_BLOCK block) { } } - LC_ASSERT(recoveryErrors == 0); + LC_ASSERT_VT(recoveryErrors == 0); } free(droppedRtpPacket); @@ -523,7 +523,7 @@ static void handleMissingPackets(PRTP_AUDIO_QUEUE queue) { // If we reach this point, we know the next packet resides in the first FEC block we're // currently waiting on. In that case, we want to wait at least until we have a second FEC // block to give up on the first one. If we don't have a second block now, just keep waiting. - LC_ASSERT(isBefore16(queue->nextRtpSequenceNumber, queue->blockHead->fecHeader.baseSequenceNumber + RTPA_DATA_SHARDS)); + LC_ASSERT_VT(isBefore16(queue->nextRtpSequenceNumber, queue->blockHead->fecHeader.baseSequenceNumber + RTPA_DATA_SHARDS)); if (queue->blockHead == queue->blockTail) { return; } diff --git a/src/RtpVideoQueue.c b/src/RtpVideoQueue.c index d957a31b..3d612542 100644 --- a/src/RtpVideoQueue.c +++ b/src/RtpVideoQueue.c @@ -1,7 +1,7 @@ #include "Limelight-internal.h" #include "rs.h" -#ifdef LC_DEBUG +#if defined(LC_DEBUG) && !defined(LC_FUZZING) // This enables FEC validation mode with a synthetic drop // and recovered packet checks vs the original input. It // is on by default for debug builds. @@ -376,15 +376,15 @@ static int reconstructFrame(PRTP_VIDEO_QUEUE queue) { int j; int recoveryErrors = 0; - LC_ASSERT(droppedDataLength <= recoveredDataLength); - LC_ASSERT(droppedDataLength == recoveredDataLength || (nvPacket->flags & FLAG_EOF)); + LC_ASSERT_VT(droppedDataLength <= recoveredDataLength); + LC_ASSERT_VT(droppedDataLength == recoveredDataLength || (nvPacket->flags & FLAG_EOF)); // Check all NV_VIDEO_PACKET fields except FEC stuff which differs in the recovered packet - LC_ASSERT(nvPacket->flags == droppedNvPacket->flags); - LC_ASSERT(nvPacket->frameIndex == droppedNvPacket->frameIndex); - LC_ASSERT(nvPacket->streamPacketIndex == droppedNvPacket->streamPacketIndex); - LC_ASSERT(nvPacket->reserved == droppedNvPacket->reserved); - LC_ASSERT(!queue->multiFecCapable || nvPacket->multiFecBlocks == droppedNvPacket->multiFecBlocks); + LC_ASSERT_VT(nvPacket->flags == droppedNvPacket->flags); + LC_ASSERT_VT(nvPacket->frameIndex == droppedNvPacket->frameIndex); + LC_ASSERT_VT(nvPacket->streamPacketIndex == droppedNvPacket->streamPacketIndex); + LC_ASSERT_VT(nvPacket->reserved == droppedNvPacket->reserved); + LC_ASSERT_VT(!queue->multiFecCapable || nvPacket->multiFecBlocks == droppedNvPacket->multiFecBlocks); // Check the data itself - use memcmp() and only loop if an error is detected if (memcmp(nvPacket + 1, droppedNvPacket + 1, droppedDataLength)) { @@ -409,7 +409,7 @@ static int reconstructFrame(PRTP_VIDEO_QUEUE queue) { } } - LC_ASSERT(recoveryErrors == 0); + LC_ASSERT_VT(recoveryErrors == 0); // This drop was fake, so we don't want to actually submit it to the depacketizer. // It will get confused because it's already seen this packet before. @@ -542,7 +542,7 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_ } // FLAG_EXTENSION is required for all supported versions of GFE. - LC_ASSERT(packet->header & FLAG_EXTENSION); + LC_ASSERT_VT(packet->header & FLAG_EXTENSION); int dataOffset = sizeof(*packet); if (packet->header & FLAG_EXTENSION) { @@ -567,11 +567,13 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_ nvPacket->multiFecFlags = 0x10; nvPacket->multiFecBlocks = 0x00; } - + +#ifndef LC_FUZZING if (isBefore16(nvPacket->frameIndex, queue->currentFrameNumber)) { // Reject frames behind our current frame number return RTPF_RET_REJECTED; } +#endif uint32_t fecIndex = (nvPacket->fecInfo & 0x3FF000) >> 12; uint8_t fecCurrentBlockNumber = (nvPacket->multiFecBlocks >> 4) & 0x3; @@ -666,7 +668,7 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_ // The check here looks weird, but that's because we increment the frame number // after successfully processing a frame. if (queue->currentFrameNumber != nvPacket->frameIndex) { - LC_ASSERT(queue->currentFrameNumber < nvPacket->frameIndex); + LC_ASSERT_VT(queue->currentFrameNumber < nvPacket->frameIndex); // If the frame immediately preceding this one was lost, we may have already // reported it using our speculative RFI logic. Don't report it again. @@ -707,19 +709,19 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_ return RTPF_RET_REJECTED; } - LC_ASSERT(!queue->fecPercentage || U16(packet->sequenceNumber - fecIndex) == queue->bufferLowestSequenceNumber); - LC_ASSERT((nvPacket->fecInfo & 0xFF0) >> 4 == queue->fecPercentage); - LC_ASSERT((nvPacket->fecInfo & 0xFFC00000) >> 22 == queue->bufferDataPackets); + LC_ASSERT_VT(!queue->fecPercentage || U16(packet->sequenceNumber - fecIndex) == queue->bufferLowestSequenceNumber); + LC_ASSERT_VT((nvPacket->fecInfo & 0xFF0) >> 4 == queue->fecPercentage); + LC_ASSERT_VT((nvPacket->fecInfo & 0xFFC00000) >> 22 == queue->bufferDataPackets); // Verify that the legacy non-multi-FEC compatibility code works - LC_ASSERT(queue->multiFecCapable || fecCurrentBlockNumber == 0); - LC_ASSERT(queue->multiFecCapable || queue->multiFecLastBlockNumber == 0); + LC_ASSERT_VT(queue->multiFecCapable || fecCurrentBlockNumber == 0); + LC_ASSERT_VT(queue->multiFecCapable || queue->multiFecLastBlockNumber == 0); // Multi-block FEC details must remain the same within a single frame - LC_ASSERT(fecCurrentBlockNumber == queue->multiFecCurrentBlockNumber); - LC_ASSERT(((nvPacket->multiFecBlocks >> 6) & 0x3) == queue->multiFecLastBlockNumber); + LC_ASSERT_VT(fecCurrentBlockNumber == queue->multiFecCurrentBlockNumber); + LC_ASSERT_VT(((nvPacket->multiFecBlocks >> 6) & 0x3) == queue->multiFecLastBlockNumber); - LC_ASSERT((nvPacket->flags & FLAG_EOF) || length - dataOffset == StreamConfig.packetSize); + LC_ASSERT_VT((nvPacket->flags & FLAG_EOF) || length - dataOffset == StreamConfig.packetSize); if (!queuePacket(queue, packetEntry, packet, length, !isBefore16(packet->sequenceNumber, queue->bufferFirstParitySequenceNumber), false)) { return RTPF_RET_REJECTED; } diff --git a/src/VideoDepacketizer.c b/src/VideoDepacketizer.c index 0ef88100..5ec1f6ee 100644 --- a/src/VideoDepacketizer.c +++ b/src/VideoDepacketizer.c @@ -198,27 +198,27 @@ void validateDecodeUnitForPlayback(PDECODE_UNIT decodeUnit) { // IDR frames always start with codec configuration data if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) { // H.264 IDR frames should have an SPS, PPS, then picture data - LC_ASSERT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_SPS); - LC_ASSERT(decodeUnit->bufferList->next != NULL); - LC_ASSERT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_PPS); - LC_ASSERT(decodeUnit->bufferList->next->next != NULL); - LC_ASSERT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PICDATA); + LC_ASSERT_VT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_SPS); + LC_ASSERT_VT(decodeUnit->bufferList->next != NULL); + LC_ASSERT_VT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_PPS); + LC_ASSERT_VT(decodeUnit->bufferList->next->next != NULL); + LC_ASSERT_VT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PICDATA); } else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) { // HEVC IDR frames should have an VPS, SPS, PPS, then picture data - LC_ASSERT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_VPS); - LC_ASSERT(decodeUnit->bufferList->next != NULL); - LC_ASSERT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_SPS); - LC_ASSERT(decodeUnit->bufferList->next->next != NULL); - LC_ASSERT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PPS); - LC_ASSERT(decodeUnit->bufferList->next->next->next != NULL); + LC_ASSERT_VT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_VPS); + LC_ASSERT_VT(decodeUnit->bufferList->next != NULL); + LC_ASSERT_VT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_SPS); + LC_ASSERT_VT(decodeUnit->bufferList->next->next != NULL); + LC_ASSERT_VT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PPS); + LC_ASSERT_VT(decodeUnit->bufferList->next->next->next != NULL); // We get 2 sets of VPS, SPS, and PPS NALUs in HDR mode. // FIXME: Should we normalize this or something for clients? } else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_AV1) { // We don't parse the AV1 bitstream - LC_ASSERT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_PICDATA); + LC_ASSERT_VT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_PICDATA); } else { LC_ASSERT(false); @@ -697,7 +697,7 @@ static void processAvcHevcRtpPayloadSlow(PBUFFER_DESC currentPos, PLENTRY_INTERN while (currentPos->length != 0) { // Any NALUs we encounter on the way to the end of the packet must be // reference frame slices or filler data. - LC_ASSERT(isSeqReferenceFrameStart(currentPos) || isFillerDataNal(currentPos)); + LC_ASSERT_VT(isSeqReferenceFrameStart(currentPos) || isFillerDataNal(currentPos)); skipToNextNalOrEnd(currentPos); } } @@ -765,7 +765,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, firstPacket = isFirstPacket(flags, fecCurrentBlockNumber); lastPacket = (flags & FLAG_EOF) && fecCurrentBlockNumber == fecLastBlockNumber; - LC_ASSERT((flags & ~(FLAG_SOF | FLAG_EOF | FLAG_CONTAINS_PIC_DATA)) == 0); + LC_ASSERT_VT((flags & ~(FLAG_SOF | FLAG_EOF | FLAG_CONTAINS_PIC_DATA)) == 0); streamPacketIndex = videoPacket->streamPacketIndex; @@ -843,10 +843,10 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, // If this is the first packet, skip the frame header (if one exists) uint32_t frameHeaderSize; - LC_ASSERT(currentPos.length > 0); + LC_ASSERT_VT(currentPos.length > 0); if (firstPacket && currentPos.length > 0) { // Parse the frame type from the header - LC_ASSERT(currentPos.length >= 4); + LC_ASSERT_VT(currentPos.length >= 4); if (APP_VERSION_AT_LEAST(7, 1, 350) && currentPos.length >= 4) { switch (currentPos.data[currentPos.offset + 3]) { case 1: // Normal P-frame @@ -874,7 +874,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, break; default: Limelog("Unrecognized frame type: %d", currentPos.data[currentPos.offset + 3]); - LC_ASSERT(false); + LC_ASSERT_VT(false); break; } } @@ -888,7 +888,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, } // Sunshine can provide host processing latency of the frame - LC_ASSERT(currentPos.length >= 3); + LC_ASSERT_VT(currentPos.length >= 3); if (IS_SUNSHINE() && currentPos.length >= 3) { BYTE_BUFFER bb; BbInitializeWrappedBuffer(&bb, currentPos.data, currentPos.offset + 1, 2, BYTE_ORDER_LITTLE); @@ -897,7 +897,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, // Codecs like H.264 and HEVC handle the FEC trailing zero padding just fine, but other // codecs need the exact length encoded separately. - LC_ASSERT(currentPos.length >= 6); + LC_ASSERT_VT(currentPos.length >= 6); if (!(NegotiatedVideoFormat & (VIDEO_FORMAT_MASK_H264 | VIDEO_FORMAT_MASK_H265)) && currentPos.length >= 6) { BYTE_BUFFER bb; BbInitializeWrappedBuffer(&bb, currentPos.data, currentPos.offset + 4, 2, BYTE_ORDER_LITTLE); @@ -912,7 +912,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, frameHeaderSize = 8; } else { - LC_ASSERT(currentPos.data[0] == (char)0x81); + LC_ASSERT_VT(currentPos.data[0] == (char)0x81); frameHeaderSize = 44; } } @@ -924,7 +924,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, frameHeaderSize = 8; } else { - LC_ASSERT(currentPos.data[0] == (char)0x81); + LC_ASSERT_VT(currentPos.data[0] == (char)0x81); frameHeaderSize = 41; } } @@ -936,7 +936,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, frameHeaderSize = 8; } else { - LC_ASSERT(currentPos.data[0] == (char)0x81); + LC_ASSERT_VT(currentPos.data[0] == (char)0x81); frameHeaderSize = 24; } } @@ -957,7 +957,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, frameHeaderSize = 0; } - LC_ASSERT(currentPos.length >= frameHeaderSize); + LC_ASSERT_VT(currentPos.length >= frameHeaderSize); if (currentPos.length >= frameHeaderSize) { // Skip past the frame header currentPos.offset += frameHeaderSize; @@ -969,7 +969,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, // The Annex B NALU start prefix must be next if (!getAnnexBStartSequence(¤tPos, NULL)) { // If we aren't starting on a start prefix, something went wrong. - LC_ASSERT(false); + LC_ASSERT_VT(false); // For release builds, we will try to recover by searching for one. // This mimics the way most decoders handle this situation. @@ -1022,11 +1022,11 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, // of trailing zero padding like H.264/HEVC Annex B bitstream parsers are. if (lastPacket) { // The payload length includes the frame header, so it cannot be smaller than that - LC_ASSERT(lastPacketPayloadLength > frameHeaderSize); + LC_ASSERT_VT(lastPacketPayloadLength > frameHeaderSize); // The payload length cannot be smaller than the actual received payload // NB: currentPos.length is already adjusted to exclude the frameHeaderSize from above - LC_ASSERT(lastPacketPayloadLength - frameHeaderSize <= currentPos.length); + LC_ASSERT_VT(lastPacketPayloadLength - frameHeaderSize <= currentPos.length); // If the payload length is valid, truncate the packet. If not, discard this frame. if (lastPacketPayloadLength > frameHeaderSize && lastPacketPayloadLength - frameHeaderSize <= currentPos.length) { diff --git a/src/VideoStream.c b/src/VideoStream.c index 3041cc23..e857100f 100644 --- a/src/VideoStream.c +++ b/src/VideoStream.c @@ -135,6 +135,7 @@ static void VideoReceiveThreadProc(void* context) { firstDataTimeMs = PltGetMillis(); } +#ifndef LC_FUZZING if (!receivedFullFrame) { uint64_t now = PltGetMillis(); @@ -144,6 +145,7 @@ static void VideoReceiveThreadProc(void* context) { break; } } +#endif if (err < (int)sizeof(RTP_PACKET)) { // Runt packet