Updated C code to remove checked arithmetic functions but retain overflow checks (related to commit 481a1c0de3).

pull/11/head
Project Nayuki 9 years ago
parent cb6835fecb
commit 02399cfd0b

@ -52,9 +52,6 @@ static int getNumRawDataModules(int version);
static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], int qrsize); static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], int qrsize);
static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], int qrsize, int mask); static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], int qrsize, int mask);
static int checkedAdd(int x, int y);
static int checkedMultiply(int x, int y);
static void calcReedSolomonGenerator(int degree, uint8_t result[]); static void calcReedSolomonGenerator(int degree, uint8_t result[]);
static void calcReedSolomonRemainder(const uint8_t data[], int dataLen, const uint8_t generator[], int degree, uint8_t result[]); static void calcReedSolomonRemainder(const uint8_t data[], int dataLen, const uint8_t generator[], int degree, uint8_t result[]);
static uint8_t finiteFieldMultiply(uint8_t x, uint8_t y); static uint8_t finiteFieldMultiply(uint8_t x, uint8_t y);
@ -112,16 +109,12 @@ int qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[
} }
} }
int textBits; long textBits;
if (isNumeric) { // textBits = textLen * 3 + ceil(textLen / 3) if (isNumeric)
textBits = checkedAdd(checkedMultiply(textLen, 3), checkedAdd(textLen, 2) / 3); textBits = textLen * 3L + (textLen + 2L) / 3;
if (textBits < 0) else if (isAlphanumeric)
return 0; textBits = textLen * 5L + (textLen + 1L) / 2;
} else if (isAlphanumeric) { // textBits = textLen * 5 + ceil(textLen / 2) else { // Use binary mode
textBits = checkedAdd(checkedMultiply(textLen, 5), checkedAdd(textLen, 1) / 2);
if (textBits < 0)
return 0;
} else { // Use binary mode
if (textLen > qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion)) if (textLen > qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion))
return 0; return 0;
for (int i = 0; i < textLen; i++) for (int i = 0; i < textLen; i++)
@ -129,7 +122,9 @@ int qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[
return qrcodegen_encodeBinary(tempBuffer, (size_t)textLen, qrcode, ecl, minVersion, maxVersion, mask, boostEcl); return qrcodegen_encodeBinary(tempBuffer, (size_t)textLen, qrcode, ecl, minVersion, maxVersion, mask, boostEcl);
} }
int version = fitVersionToData(minVersion, maxVersion, ecl, textLen, textBits, if (textBits > INT_MAX)
return 0;
int version = fitVersionToData(minVersion, maxVersion, ecl, textLen, (int)textBits,
(isNumeric ? 10 : 9), (isNumeric ? 12 : 11), (isNumeric ? 14 : 13)); (isNumeric ? 10 : 9), (isNumeric ? 12 : 11), (isNumeric ? 14 : 13));
if (version == 0) if (version == 0)
return 0; return 0;
@ -214,8 +209,11 @@ static int fitVersionToData(int minVersion, int maxVersion, enum qrcodegen_Ecc e
if (dataLen >= (1L << lengthBits)) if (dataLen >= (1L << lengthBits))
continue; continue;
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available
int dataUsedBits = checkedAdd(4 + lengthBits, dataBitLen); int dataUsedBits = 4 + lengthBits;
if (0 <= dataUsedBits && dataUsedBits <= dataCapacityBits) if (dataBitLen > INT_MAX - dataUsedBits)
continue;
dataUsedBits += dataBitLen;
if (dataUsedBits <= dataCapacityBits)
return version; // This version number is found to be suitable return version; // This version number is found to be suitable
if (version >= maxVersion) // All versions in the range could not fit the given data if (version >= maxVersion) // All versions in the range could not fit the given data
return 0; return 0;
@ -669,26 +667,6 @@ static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], i
} }
// Tries to add the given non-negative integers, with strict overflow checking.
// Negative inputs or output indicate the computation would overflow.
static int checkedAdd(int x, int y) {
if (x < 0 || y < 0 || x > INT_MAX - y)
return -1;
else
return x + y;
}
// Tries to multiply the given non-negative integers, with strict overflow checking.
// Negative inputs or output indicate the computation would overflow.
static int checkedMultiply(int x, int y) {
if (x < 0 || y < 0 || x > INT_MAX / y)
return -1;
else
return x * y;
}
/*---- Reed-Solomon ECC generator functions ----*/ /*---- Reed-Solomon ECC generator functions ----*/

Loading…
Cancel
Save