Updated C++ ByteBuffer and QrSegment code to check and handle integer overflow strictly.
This commit is contained in:
parent
b7a4605e44
commit
873652a82f
|
@ -22,6 +22,7 @@
|
||||||
* Software.
|
* Software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include "BitBuffer.hpp"
|
#include "BitBuffer.hpp"
|
||||||
|
|
||||||
|
@ -44,8 +45,10 @@ std::vector<uint8_t> qrcodegen::BitBuffer::getBytes() const {
|
||||||
void qrcodegen::BitBuffer::appendBits(uint32_t val, int len) {
|
void qrcodegen::BitBuffer::appendBits(uint32_t val, int len) {
|
||||||
if (len < 0 || len > 32 || (len < 32 && (val >> len) != 0))
|
if (len < 0 || len > 32 || (len < 32 && (val >> len) != 0))
|
||||||
throw "Value out of range";
|
throw "Value out of range";
|
||||||
size_t newBitLen = bitLength + len;
|
if (INT_MAX - bitLength < len)
|
||||||
while (data.size() * 8 < newBitLen)
|
throw "Buffer too long";
|
||||||
|
unsigned int newByteLen = ((unsigned int)bitLength + len + 7) / 8;
|
||||||
|
while (data.size() < newByteLen)
|
||||||
data.push_back(0);
|
data.push_back(0);
|
||||||
for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit
|
for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit
|
||||||
data.at(bitLength >> 3) |= ((val >> i) & 1) << (7 - (bitLength & 7));
|
data.at(bitLength >> 3) |= ((val >> i) & 1) << (7 - (bitLength & 7));
|
||||||
|
@ -53,8 +56,10 @@ void qrcodegen::BitBuffer::appendBits(uint32_t val, int len) {
|
||||||
|
|
||||||
|
|
||||||
void qrcodegen::BitBuffer::appendData(const QrSegment &seg) {
|
void qrcodegen::BitBuffer::appendData(const QrSegment &seg) {
|
||||||
size_t newBitLen = bitLength + seg.bitLength;
|
if (INT_MAX - bitLength < seg.bitLength)
|
||||||
while (data.size() * 8 < newBitLen)
|
throw "Buffer too long";
|
||||||
|
unsigned int newByteLen = ((unsigned int)bitLength + seg.bitLength + 7) / 8;
|
||||||
|
while (data.size() < newByteLen)
|
||||||
data.push_back(0);
|
data.push_back(0);
|
||||||
for (int i = 0; i < seg.bitLength; i++, bitLength++) { // Append bit by bit
|
for (int i = 0; i < seg.bitLength; i++, bitLength++) { // Append bit by bit
|
||||||
int bit = (seg.data.at(i >> 3) >> (7 - (i & 7))) & 1;
|
int bit = (seg.data.at(i >> 3) >> (7 - (i & 7))) & 1;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
* Software.
|
* Software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include "BitBuffer.hpp"
|
#include "BitBuffer.hpp"
|
||||||
#include "QrSegment.hpp"
|
#include "QrSegment.hpp"
|
||||||
|
@ -139,7 +140,10 @@ int qrcodegen::QrSegment::getTotalBits(const std::vector<QrSegment> &segs, int v
|
||||||
// Fail if segment length value doesn't fit in the length field's bit-width
|
// Fail if segment length value doesn't fit in the length field's bit-width
|
||||||
if (seg.numChars >= (1 << ccbits))
|
if (seg.numChars >= (1 << ccbits))
|
||||||
return -1;
|
return -1;
|
||||||
result += 4 + ccbits + seg.bitLength;
|
long temp = (long)result + 4 + ccbits + seg.bitLength;
|
||||||
|
if (temp > INT_MAX)
|
||||||
|
return -1;
|
||||||
|
result = temp;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue