diff --git a/libraries/shared/src/OctalCode.cpp b/libraries/shared/src/OctalCode.cpp index c0f1ccfa62..027a6a4d68 100644 --- a/libraries/shared/src/OctalCode.cpp +++ b/libraries/shared/src/OctalCode.cpp @@ -16,10 +16,15 @@ #include "SharedUtil.h" #include "OctalCode.h" -int numberOfThreeBitSectionsInCode(const unsigned char* octalCode) { +int numberOfThreeBitSectionsInCode(const unsigned char* octalCode, int maxBytes) { + if (maxBytes == OVERFLOWED_OCTCODE_BUFFER) { + return OVERFLOWED_OCTCODE_BUFFER; + } + assert(octalCode); if (*octalCode == 255) { - return *octalCode + numberOfThreeBitSectionsInCode(octalCode + 1); + int newMaxBytes = (maxBytes == UNKNOWN_OCTCODE_LENGTH) ? UNKNOWN_OCTCODE_LENGTH : maxBytes - 1; + return *octalCode + numberOfThreeBitSectionsInCode(octalCode + 1, newMaxBytes); } else { return *octalCode; } diff --git a/libraries/shared/src/OctalCode.h b/libraries/shared/src/OctalCode.h index 27746474eb..34d4264de4 100644 --- a/libraries/shared/src/OctalCode.h +++ b/libraries/shared/src/OctalCode.h @@ -24,7 +24,15 @@ void printOctalCode(const unsigned char* octalCode); int bytesRequiredForCodeLength(unsigned char threeBitCodes); int branchIndexWithDescendant(const unsigned char* ancestorOctalCode, const unsigned char* descendantOctalCode); unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNumber); -int numberOfThreeBitSectionsInCode(const unsigned char* octalCode); + +const int OVERFLOWED_OCTCODE_BUFFER = -1; +const int UNKNOWN_OCTCODE_LENGTH = -2; + +/// will return -1 if there is an error in the octcode encoding, or it would overflow maxBytes +/// \param const unsigned char* octalCode the octalcode to decode +/// \param int maxBytes number of bytes that octalCode is expected to be, -1 if unknown +int numberOfThreeBitSectionsInCode(const unsigned char* octalCode, int maxBytes = UNKNOWN_OCTCODE_LENGTH); + unsigned char* chopOctalCode(const unsigned char* originalOctalCode, int chopLevels); unsigned char* rebaseOctalCode(const unsigned char* originalOctalCode, const unsigned char* newParentOctalCode, bool includeColorSpace = false); diff --git a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp index 53a6267a7a..a547f441db 100644 --- a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp +++ b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp @@ -49,7 +49,15 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned int atByte = numBytesPacketHeader + sizeof(itemNumber); unsigned char* voxelData = (unsigned char*)&packetData[atByte]; while (atByte < packetLength) { - unsigned char octets = numberOfThreeBitSectionsInCode(voxelData); + int maxSize = packetLength - atByte; + unsigned char octets = numberOfThreeBitSectionsInCode(voxelData, maxSize); + + if (octets == OVERFLOWED_OCTCODE_BUFFER) { + printf("WARNING! Got voxel edit record that would overflow buffer in numberOfThreeBitSectionsInCode(), "); + printf("bailing processing of packet!\n"); + break; + } + const int COLOR_SIZE_IN_BYTES = 3; int voxelDataSize = bytesRequiredForCodeLength(octets) + COLOR_SIZE_IN_BYTES; int voxelCodeSize = bytesRequiredForCodeLength(octets); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index f7f50788c5..57c99c5ff8 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -581,7 +581,14 @@ void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int buffe int atByte = sizeof(short int) + numBytesForPacketHeader(bitstream); unsigned char* voxelCode = (unsigned char*)&bitstream[atByte]; while (atByte < bufferSizeBytes) { - int codeLength = numberOfThreeBitSectionsInCode(voxelCode); + int maxSize = bufferSizeBytes - atByte; + unsigned char codeLength = numberOfThreeBitSectionsInCode(voxelCode, maxSize); + + if (codeLength == OVERFLOWED_OCTCODE_BUFFER) { + printf("WARNING! Got remove voxel bitstream that would overflow buffer in numberOfThreeBitSectionsInCode(), "); + printf("bailing processing of packet!\n"); + break; + } int voxelDataSize = bytesRequiredForCodeLength(codeLength) + SIZE_OF_COLOR_DATA; if (atByte + voxelDataSize <= bufferSizeBytes) {