fix undefined behavior: left shift a negative integer

C/C++ leaves left-shifting a negative integer up to the compiler
implementation.

On most platforms, left-shifting a negative integer is the same as
casting to the unsigned equivalent, then casting back into the signed
type.

This replaces the left-shift with the mathematical equivalent and avoids
the undefined behavior.

Ideally this should be performed for any case of left-shifting a signed
type, but this commit only covers cases picked up by the undefined
behavior sanitizer.
This commit is contained in:
John Regan 2022-07-07 10:35:08 -04:00
parent c2665b890c
commit 5cc33e5af7
6 changed files with 11 additions and 11 deletions

View File

@ -277,7 +277,7 @@ unsigned BasicWavReader::readDataLnPcm16 (const int fileHandle, int32_t* frameBu
for (unsigned i = read * chanCount; i > 0; i--)
{
*(frameBuf++) = (int32_t) *(iBuf++) << 8; // * 2^8
*(frameBuf++) = (int32_t) *(iBuf++) * (1 << 8); // * 2^8
}
framesRead += read;
}

View File

@ -28,7 +28,7 @@ void eaExtrapolate (int32_t* const pcmBuffer, const uint16_t pcmOffset, // start
for (uint16_t ch = 0; ch < numChannels; ch++)
{
int32_t* chPcmBuf = pcmBuffer + ch + (pcmOffset - (fadeIn ? 0 : 1)) * numChannels;
int32_t result32 = (pcmOffset == 0 ? 0 : *chPcmBuf << 8); // input is known to be 24-bit PCM
int32_t result32 = (pcmOffset == 0 ? 0 : *chPcmBuf * (1 << 8)); // input is known to be 24-bit PCM
const int32_t s32 = result32 / size;
for (uint16_t i = size; i > 0; i--) *(chPcmBuf += delta) = ((result32 -= s32) + 128) >> 8;

View File

@ -80,7 +80,7 @@ uint32_t LoudnessEstimator::addNewPcmData (const unsigned samplesPerChannel)
const int64_t pi = filtI[0] * i[0] + filtI[1] * i[1] + filtI[2] * i[2] + filtI[3] * i[3] -
filtO[0] * o[0] - filtO[1] * o[1] - filtO[2] * o[2] - filtO[3] * o[3];
const int64_t to = (pi < 0 ? (1 << 28) - 1 : 0); // trunc. offset
const int32_t xi = (*(chSig++)) << 2;
const int32_t xi = (*(chSig++)) * (1 << 2);
const int32_t yi = xi + int32_t ((pi + (xi == 0 ? to : (1 << 27))) >> 28);
const uint32_t a = abs (xi >> 2);

View File

@ -190,8 +190,8 @@ uint32_t LinearPredictor::calcParCorCoeffs (const int32_t* const anaSignal, cons
for (p = s; p < nCoeffs; p++)
{
sampleHO = EN[p - s]; // use register?
EN[p - s] = (EN[p - s] << 9) + EP[p] * Ks;
EP[p] = (EP[p] << 9) + sampleHO * Ks;
EN[p - s] = (EN[p - s] * (1 << 9)) + EP[p] * Ks;
EP[p] = (EP[p] * (1 << 9)) + sampleHO * Ks;
}
if (s > 0 && EN[0] < 0) // EN wrap-around
{
@ -255,11 +255,11 @@ uint8_t LinearPredictor::calcOptTnsCoeffs (short* const parCorCoeffs, int8_t* co
}
// determine direct-form filter damping factor
parCorCoeffs[0] <<= bitShift;
parCorCoeffs[0] *= 1 << bitShift;
i = abs (parCorCoeffs[0]);
for (s = 1; s < order; s++)
{
parCorCoeffs[s] <<= bitShift; // scale coeff
parCorCoeffs[s] *= 1 << bitShift; // scale coeff
i = __max (i, abs (parCorCoeffs[s]));
}
for (/*s*/; s < MAX_PREDICTION_ORDER; s++)
@ -343,7 +343,7 @@ unsigned LinearPredictor::lpToParCorCoeffs (/*mod!*/short* const lpCoeffs, const
}
for (p = 0; p < s; p++)
{
lpCoeffs[p] = short ((o + ((int) lpCoeffs[p] << shift) - intBuf[p] * i) / d);
lpCoeffs[p] = short ((o + ((int) lpCoeffs[p] * (1 << shift)) - intBuf[p] * i) / d);
}
}
parCorCoeffs[0] = lpCoeffs[0];

View File

@ -268,7 +268,7 @@ uint8_t SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuantizer, c
{
unsigned countOld = 0, countNew = 0;
b = CLIP_PM (((b << 8) + (a >> 1)) / a, SHRT_MAX);
b = CLIP_PM (((b * (1 << 8)) + (a >> 1)) / a, SHRT_MAX);
a = ((ySum << 8) - b * xSum + (size >> 1)) / size;
ySum = grpScFacs[start];

View File

@ -210,7 +210,7 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
for (int i = nSamplesInFrame >> sbrShift; i > 0; i--, lrSig++, hrSig += 2)
{
int64_t r = ((int64_t) hrSig[0] << 17) + (hrSig[-1] + (int64_t) hrSig[1]) * -2*SHRT_MIN;
int64_t r = ((int64_t) hrSig[0] * (1 << 17)) + (hrSig[-1] + (int64_t) hrSig[1]) * -2*SHRT_MIN;
int16_t s;
for (u = 65, s = 129; u > 0; s -= 2) r += (hrSig[-s] + (int64_t) hrSig[s]) * lpfc12[--u];
@ -222,7 +222,7 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
if ((i & 1) != 0) // compute quarter-rate mid-frequency SBR signal
{
r = ((3 * (int64_t) hrSig[0]) << 16) - (hrSig[-1] + (int64_t) hrSig[1]) * SHRT_MIN - r;
r = ((3 * (int64_t) hrSig[0]) * (1 << 16)) - (hrSig[-1] + (int64_t) hrSig[1]) * SHRT_MIN - r;
r += (hrSig[-2] + (int64_t) hrSig[2]) * SHRT_MIN;
for (s = 127; s > 0; s--/*u = s*/) r += (hrSig[-s] + (int64_t) hrSig[s]) * lpfc34[s];