1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-18 17:10:05 +02:00

Make many conversions sampleCount->size_t are explicit and checked...

... with run-time assertions.

I examined each place and reasoned that the narrowing was safe, and commented
why so.

Again, there are places where the sampleCount variable will later be changed
to have a different type, and they are not changed here.
This commit is contained in:
Paul Licameli 2016-08-31 00:49:22 -04:00
parent 78be459fa1
commit 078ff056e2
17 changed files with 220 additions and 77 deletions

View File

@ -74,6 +74,12 @@ public:
long long as_long_long() const { return value; }
size_t as_size_t() const {
wxASSERT(value >= 0);
wxASSERT(value <= std::numeric_limits<size_t>::max());
return value;
}
sampleCount &operator += (sampleCount b) { value += b.value; return *this; }
sampleCount &operator -= (sampleCount b) { value -= b.value; return *this; }
sampleCount &operator *= (sampleCount b) { value *= b.value; return *this; }

View File

@ -592,7 +592,8 @@ struct AudioIO::ScrubQueue
auto remaining = pEntry->mDuration - pEntry->mPlayed;
if (frames >= remaining)
{
frames -= remaining;
// remaining is not more than frames
frames -= remaining.as_size_t();
pEntry->mPlayed = pEntry->mDuration;
}
else

View File

@ -569,7 +569,8 @@ void FreqWindow::GetAudio()
mDataLen = 10485760;
}
else
mDataLen = dataLen;
// dataLen is not more than 10 * 2 ^ 20
mDataLen = dataLen.as_size_t();
mData = new float[mDataLen];
track->Get((samplePtr)mData, floatSample, start, mDataLen);
}

View File

@ -633,7 +633,12 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
//delete[] rmsRight;
auto startSample = (sampleCount)((mLeftTrack->GetRate() * t0) + 0.5);
auto nFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5);
auto scnFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5);
// Expect that the difference of t1 and t0 is the part of a track played
// in about 1/20 second (ticks of TrackPanel timer), so this won't overflow
auto nFrames = scnFrames.as_size_t();
float* meterFloatsArray = NULL;
float* tempFloatsArray = new float[nFrames];
bool bSuccess = mLeftTrack->Get((samplePtr)tempFloatsArray, floatSample, startSample, nFrames);

View File

@ -264,8 +264,12 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len,
theFile->GetMinMax(&block0Min, &block0Max, &block0RMS);
if (block0Min < min || block0Max > max) {
auto s0 = start - theBlock.start;
const auto maxl0 = theBlock.start + theFile->GetLength() - start;
// start lies within theBlock:
auto s0 = ( start - theBlock.start ).as_size_t();
const auto maxl0 = (
// start lies within theBlock:
theBlock.start + theFile->GetLength() - start
).as_size_t();
wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19
const auto l0 = limitSampleBufferSize ( maxl0, len );
@ -288,7 +292,8 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len,
if (block1Min < min || block1Max > max) {
const auto l0 = (start + len) - theBlock.start;
// start + len - 1 lies in theBlock:
const auto l0 = ( start + len - theBlock.start ).as_size_t();
wxASSERT(l0 <= mMaxSamples); // Vaughan, 2011-10-19
float partialMin, partialMax, partialRMS;
@ -343,8 +348,11 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
{
const SeqBlock &theBlock = mBlock[block0];
const auto &theFile = theBlock.f;
auto s0 = start - theBlock.start;
const auto maxl0 = theBlock.start + theFile->GetLength() - start;
// start lies within theBlock
auto s0 = ( start - theBlock.start ).as_size_t();
// start lies within theBlock
const auto maxl0 =
(theBlock.start + theFile->GetLength() - start).as_size_t();
wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19
const auto l0 = limitSampleBufferSize( maxl0, len );
@ -359,7 +367,8 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
const SeqBlock &theBlock = mBlock[block1];
const auto &theFile = theBlock.f;
const auto l0 = (start + len) - theBlock.start;
// start + len - 1 lies within theBlock
const auto l0 = ( start + len - theBlock.start ).as_size_t();
wxASSERT(l0 <= mMaxSamples); // PRL: I think Vaughan missed this
float partialMin, partialMax, partialRMS;
@ -405,7 +414,9 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &d
const SeqBlock &block0 = mBlock[b0];
if (s0 != block0.start) {
const auto &file = block0.f;
blocklen = std::min(s1, block0.start + file->GetLength()) - s0;
// Nonnegative result is length of block0 or less:
blocklen =
( std::min(s1, block0.start + file->GetLength()) - s0 ).as_size_t();
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
Get(b0, buffer.ptr(), mSampleFormat, s0, blocklen);
@ -422,7 +433,8 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &d
if (b1 > b0) {
const SeqBlock &block = mBlock[b1];
const auto &file = block.f;
blocklen = (s1 - block.start);
// s1 is within block:
blocklen = (s1 - block.start).as_size_t();
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
if (blocklen < file->GetLength()) {
Get(b1, buffer.ptr(), mSampleFormat, block.start, blocklen);
@ -512,18 +524,24 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
// one block!
SeqBlock &block = *pBlock;
SampleBuffer buffer(largerBlockLen, mSampleFormat);
// largerBlockLen is not more than mMaxSamples...
SampleBuffer buffer(largerBlockLen.as_size_t(), mSampleFormat);
int splitPoint = s - block.start;
// ...and addedLen is not more than largerBlockLen
auto sAddedLen = addedLen.as_size_t();
// s lies within block:
auto splitPoint = ( s - block.start ).as_size_t();
Read(buffer.ptr(), mSampleFormat, block, 0, splitPoint);
src->Get(0, buffer.ptr() + splitPoint*sampleSize,
mSampleFormat, 0, addedLen);
Read(buffer.ptr() + (splitPoint + addedLen)*sampleSize,
mSampleFormat, 0, sAddedLen);
Read(buffer.ptr() + (splitPoint + sAddedLen) * sampleSize,
mSampleFormat, block,
splitPoint, length - splitPoint);
auto file =
mDirManager->NewSimpleBlockFile(buffer.ptr(), largerBlockLen, mSampleFormat);
mDirManager->NewSimpleBlockFile(
// largerBlockLen is not more than mMaxSamples...
buffer.ptr(), largerBlockLen.as_size_t(), mSampleFormat);
block.f = file;
@ -545,19 +563,22 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
SeqBlock &splitBlock = mBlock[b];
auto splitLen = splitBlock.f->GetLength();
int splitPoint = s - splitBlock.start;
// s lies within splitBlock
auto splitPoint = ( s - splitBlock.start ).as_size_t();
unsigned int i;
if (srcNumBlocks <= 4) {
sampleCount sum = splitLen + addedLen;
// addedLen is at most four times maximum block size
auto sAddedLen = addedLen.as_size_t();
const auto sum = splitLen + sAddedLen;
SampleBuffer sumBuffer(sum, mSampleFormat);
Read(sumBuffer.ptr(), mSampleFormat, splitBlock, 0, splitPoint);
src->Get(0, sumBuffer.ptr() + splitPoint * sampleSize,
mSampleFormat,
0, addedLen);
Read(sumBuffer.ptr() + (splitPoint + addedLen) * sampleSize, mSampleFormat,
0, sAddedLen);
Read(sumBuffer.ptr() + (splitPoint + sAddedLen) * sampleSize, mSampleFormat,
splitBlock, splitPoint,
splitLen - splitPoint);
@ -646,7 +667,10 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
sampleCount pos = 0;
sTrack.mBlock.reserve((len + idealSamples - 1) / idealSamples);
// Could nBlocks overflow a size_t? Not very likely. You need perhaps
// 2 ^ 52 samples which is over 3000 years at 44.1 kHz.
auto nBlocks = (len + idealSamples - 1) / idealSamples;
sTrack.mBlock.reserve(nBlocks.as_size_t());
BlockFilePtr silentFile {};
if (len >= idealSamples)
@ -659,7 +683,8 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
}
if (len != 0) {
sTrack.mBlock.push_back(SeqBlock(
make_blockfile<SilentBlockFile>(len), pos));
// len is not more than idealSamples:
make_blockfile<SilentBlockFile>( len.as_size_t() ), pos));
pos += len;
}
@ -770,7 +795,8 @@ sampleCount Sequence::GetBestBlockSize(sampleCount start) const
int numBlocks = mBlock.size();
const SeqBlock &block = mBlock[b];
sampleCount result = (block.start + block.f->GetLength() - start);
// start is in block:
auto result = (block.start + block.f->GetLength() - start).as_size_t();
decltype(result) length;
while(result < mMinSamples && b+1<numBlocks &&
@ -943,7 +969,8 @@ void Sequence::HandleXMLEndTag(const wxChar *tag)
Internat::ToString((double)mMaxSamples, 0).c_str());
len = mMaxSamples;
}
block.f = make_blockfile<SilentBlockFile>(len);
// len is at most mMaxSamples:
block.f = make_blockfile<SilentBlockFile>( len.as_size_t() );
wxLogWarning(
wxT("Gap detected in project file. Replacing missing block file with silence."));
mErrorOpening = true;
@ -1148,7 +1175,9 @@ bool Sequence::Get(int b, samplePtr buffer, sampleFormat format,
{
while (len) {
const SeqBlock &block = mBlock[b];
const sampleCount bstart = (start - (block.start));
// start is in block
const auto bstart = (start - block.start).as_size_t();
// bstart is not more than block length
const auto blen = std::min(len, block.f->GetLength() - bstart);
Read(buffer, format, block, bstart, blen);
@ -1182,7 +1211,8 @@ bool Sequence::Set(samplePtr buffer, sampleFormat format,
while (len != 0) {
SeqBlock &block = mBlock[b];
const sampleCount bstart = start - block.start;
// start is within block
const auto bstart = ( start - block.start ).as_size_t();
const auto fileLength = block.f->GetLength();
const auto blen = limitSampleBufferSize( fileLength - bstart, len );
@ -1343,10 +1373,14 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
int blockStatus = b;
// How many samples or triples are needed?
const sampleCount startPosition =
std::max(sampleCount(0), (srcX - start) / divisor);
const sampleCount inclusiveEndPosition =
std::min((mMaxSamples / divisor) - 1, (nextSrcX - 1 - start) / divisor);
const size_t startPosition =
// srcX and start are in the same block
std::max(sampleCount(0), (srcX - start) / divisor).as_size_t();
const size_t inclusiveEndPosition =
// nextSrcX - 1 and start are in the same block
std::min((sampleCount(mMaxSamples) / divisor) - 1,
(nextSrcX - 1 - start) / divisor).as_size_t();
const auto num = 1 + inclusiveEndPosition - startPosition;
if (num <= 0) {
// What? There was a zero length block file?
@ -1392,7 +1426,8 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
// The previous pixel column might straddle blocks.
// If so, impute some of the data to it.
if (b > block0 && pixel > 0) {
sampleCount midPosition = (whereNow - start) / divisor;
// whereNow and start are in the same block
auto midPosition = ((whereNow - start) / divisor).as_size_t();
int diff(midPosition - filePosition);
if (diff > 0) {
MinMaxSumsq values(temp, diff, divisor);
@ -1423,7 +1458,9 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
decltype(filePosition) positionX = 0;
while (pixelX < nextPixel &&
filePosition ==
(positionX = (std::min(s1 - 1, where[pixelX]) - start) / divisor)
(positionX = (
// s1 - 1 or where[pixelX] and start are in the same block
(std::min(s1 - 1, where[pixelX]) - start) / divisor).as_size_t() )
)
++pixelX;
if (pixelX >= nextPixel)
@ -1608,14 +1645,21 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
if (b0 == b1 && (length = (pBlock = &mBlock[b0])->f->GetLength()) - len >= mMinSamples) {
SeqBlock &b = *pBlock;
sampleCount pos = start - b.start;
sampleCount newLen = length - len;
// start is within block
auto pos = ( start - b.start ).as_size_t();
wxASSERT(len < length);
// len must be less than length
// because start + len - 1 is also in the block...
auto newLen = ( length - len ).as_size_t();
scratch.Allocate(scratchSize, mSampleFormat);
Read(scratch.ptr(), mSampleFormat, b, 0, pos);
Read(scratch.ptr() + (pos * sampleSize), mSampleFormat,
b, pos + len, newLen - pos);
b,
// ... and therefore pos + len
// is not more than the length of the block
( pos + len ).as_size_t(), newLen - pos);
b = SeqBlock(
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat),
@ -1645,7 +1689,8 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
// Otherwise combine it with the previous block (splitting them
// 50/50 if necessary).
const SeqBlock &preBlock = mBlock[b0];
sampleCount preBufferLen = start - preBlock.start;
// start is within preBlock
auto preBufferLen = ( start - preBlock.start ).as_size_t();
if (preBufferLen) {
if (preBufferLen >= mMinSamples || b0 == 0) {
if (!scratch.ptr())
@ -1682,14 +1727,17 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
// the array, write it out. Otherwise combine it with the
// subsequent block (splitting them 50/50 if necessary).
const SeqBlock &postBlock = mBlock[b1];
sampleCount postBufferLen =
(postBlock.start + postBlock.f->GetLength()) - (start + len);
// start + len - 1 lies within postBlock
const auto postBufferLen = (
(postBlock.start + postBlock.f->GetLength()) - (start + len)
).as_size_t();
if (postBufferLen) {
if (postBufferLen >= mMinSamples || b1 == numBlocks - 1) {
if (!scratch.ptr())
// Last use of scratch, can ask for smaller
scratch.Allocate(postBufferLen, mSampleFormat);
sampleCount pos = (start + len) - postBlock.start;
// start + len - 1 lies within postBlock
auto pos = (start + len - postBlock.start).as_size_t();
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen);
auto file =
mDirManager->NewSimpleBlockFile(scratch.ptr(), postBufferLen, mSampleFormat);
@ -1703,7 +1751,8 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
if (!scratch.ptr())
// Last use of scratch, can ask for smaller
scratch.Allocate(sum, mSampleFormat);
sampleCount pos = (start + len) - postBlock.start;
// start + len - 1 lies within postBlock
auto pos = (start + len - postBlock.start).as_size_t();
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen);
Read(scratch.ptr() + (postBufferLen * sampleSize), mSampleFormat,
postpostBlock, 0, postpostLen);

View File

@ -1319,7 +1319,11 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &
const double t1 = zoomInfo.PositionToTime(rect.width - 1, -leftOffset) - toffset;
const auto s1 = sampleCount(ceil(t1 * rate));
sampleCount slen = std::min(snSamples - s0, s1 - s0 + 1);
// Assume size_t will not overflow, else we wouldn't be here drawing the
// few individual samples
auto slen = std::min(snSamples - s0, s1 - s0 + 1).as_size_t();
if (slen <= 0)
return;

View File

@ -4575,7 +4575,9 @@ void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event )
//Go from the smaller to larger sample.
const auto start = std::min( s0, mDrawingLastDragSample);
const auto end = std::max( s0, mDrawingLastDragSample);
const int size = end - start + 1;
// Few enough samples to be drawn individually on screen will not
// overflow size_t:
const auto size = ( end - start + 1 ).as_size_t();
if (size == 1) {
mDrawingTrack->Set((samplePtr)&newLevel, floatSample, start, size);
}
@ -4583,7 +4585,8 @@ void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event )
std::vector<float> values(size);
for (auto i = start; i <= end; ++i) {
//This interpolates each sample linearly:
values[i - start] =
// i - start will not overflow size_t either:
values[( i - start ).as_size_t()] =
mDrawingLastDragSampleValue + (newLevel - mDrawingLastDragSampleValue) *
(i - mDrawingLastDragSample).as_float() /
(s0 - mDrawingLastDragSample).as_float();

View File

@ -645,13 +645,16 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
if (right > left) {
float *b;
sampleCount len = right-left;
// left is nonnegative and at most mAppendBufferLen:
auto sLeft = left.as_size_t();
// The difference is at most mAppendBufferLen:
size_t len = ( right - left ).as_size_t();
if (seqFormat == floatSample)
b = &((float *)mAppendBuffer.ptr())[left];
b = &((float *)mAppendBuffer.ptr())[sLeft];
else {
b = new float[len];
CopySamples(mAppendBuffer.ptr() + left*SAMPLE_SIZE(seqFormat),
CopySamples(mAppendBuffer.ptr() + sLeft * SAMPLE_SIZE(seqFormat),
seqFormat,
(samplePtr)b, floatSample, len);
}
@ -831,7 +834,8 @@ bool SpecCache::CalculateOneSpectrum
if (start + myLen > numSamples) {
// Near the end of the clip, pad right with zeroes as needed.
int newlen = numSamples - start;
// newlen is bounded by myLen:
auto newlen = ( numSamples - start ).as_size_t();
for (decltype(myLen) ii = newlen; ii < myLen; ++ii)
adj[ii] = 0;
myLen = newlen;

View File

@ -2042,11 +2042,24 @@ bool WaveTrack::Get(samplePtr buffer, sampleFormat format,
{
inclipDelta = -startDelta; // make positive value
samplesToCopy -= inclipDelta;
// samplesToCopy is now either len or
// (clipEnd - clipStart) - (start - clipStart)
// == clipEnd - start > 0
// samplesToCopy is not more than len
//
startDelta = 0;
// startDelta is zero
}
else {
// startDelta is nonnegative and less than than len
// samplesToCopy is positive and not more than len
}
if (!clip->GetSamples((samplePtr)(((char*)buffer)+startDelta*SAMPLE_SIZE(format)),
format, inclipDelta, samplesToCopy))
if (!clip->GetSamples(
(samplePtr)(((char*)buffer) +
startDelta.as_size_t() *
SAMPLE_SIZE(format)),
format, inclipDelta, samplesToCopy.as_size_t() ))
{
wxASSERT(false); // should always work
return false;
@ -2078,11 +2091,24 @@ bool WaveTrack::Set(samplePtr buffer, sampleFormat format,
{
inclipDelta = -startDelta; // make positive value
samplesToCopy -= inclipDelta;
// samplesToCopy is now either len or
// (clipEnd - clipStart) - (start - clipStart)
// == clipEnd - start > 0
// samplesToCopy is not more than len
//
startDelta = 0;
// startDelta is zero
}
else {
// startDelta is nonnegative and less than than len
// samplesToCopy is positive and not more than len
}
if (!clip->SetSamples((samplePtr)(((char*)buffer)+startDelta*SAMPLE_SIZE(format)),
format, inclipDelta, samplesToCopy))
if (!clip->SetSamples(
(samplePtr)(((char*)buffer) +
startDelta.as_size_t() *
SAMPLE_SIZE(format)),
format, inclipDelta, samplesToCopy.as_size_t() ))
{
wxASSERT(false); // should always work
return false;
@ -2128,10 +2154,13 @@ void WaveTrack::GetEnvelopeValues(double *buffer, size_t bufferLen,
if (rt0 < dClipStartTime)
{
// This is not more than the number of samples in
// (endTime - startTime) which is bufferLen:
auto nDiff = (sampleCount)floor((dClipStartTime - rt0) * mRate + 0.5);
rbuf += nDiff;
wxASSERT(nDiff <= rlen);
rlen -= nDiff;
auto snDiff = nDiff.as_size_t();
rbuf += snDiff;
wxASSERT(snDiff <= rlen);
rlen -= snDiff;
rt0 = dClipStartTime;
}
@ -2722,30 +2751,45 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
if (initLen > 0) {
// This might be fetching zeroes between clips
mOverlapBuffer.Resize(len, format);
if (!mPTrack->Get(mOverlapBuffer.ptr(), format, start, initLen))
// initLen is not more than len:
auto sinitLen = initLen.as_size_t();
if (!mPTrack->Get(mOverlapBuffer.ptr(), format, start, sinitLen))
return 0;
remaining -= initLen;
wxASSERT( sinitLen <= remaining );
remaining -= sinitLen;
start += initLen;
buffer = mOverlapBuffer.ptr() + initLen * SAMPLE_SIZE(format);
buffer = mOverlapBuffer.ptr() + sinitLen * SAMPLE_SIZE(format);
}
// Now satisfy the request from the buffers
for (int ii = 0; ii < mNValidBuffers && remaining > 0; ++ii) {
const auto starti = start - mBuffers[ii].start;
// Treatment of initLen above establishes this loop invariant,
// and statements below preserve it:
wxASSERT(starti >= 0);
// This may be negative
const auto leni =
std::min( sampleCount( remaining ), mBuffers[ii].len - starti );
if (initLen <= 0 && leni == len) {
// All is contiguous already. We can completely avoid copying
return samplePtr(mBuffers[ii].data + starti);
// leni is nonnegative, therefore start falls within mBuffers[ii],
// so starti is bounded between 0 and buffer length
return samplePtr(mBuffers[ii].data + starti.as_size_t() );
}
else if (leni > 0) {
// leni is nonnegative, therefore start falls within mBuffers[ii]
// But we can't satisfy all from one buffer, so copy
if (buffer == 0) {
mOverlapBuffer.Resize(len, format);
buffer = mOverlapBuffer.ptr();
}
const size_t size = sizeof(float) * leni;
memcpy(buffer, mBuffers[ii].data + starti, size);
remaining -= leni;
// leni is positive and not more than remaining
const size_t size = sizeof(float) * leni.as_size_t();
// starti is less than mBuffers[ii].len and nonnegative
memcpy(buffer, mBuffers[ii].data + starti.as_size_t(), size);
wxASSERT( leni <= remaining );
remaining -= leni.as_size_t();
start += leni;
buffer += size;
}

View File

@ -312,7 +312,9 @@ bool EffectAutoDuck::Process()
for (auto i = pos; i < pos + len; i++)
{
rmsSum -= rmsWindow[rmsPos];
rmsWindow[rmsPos] = buf[i - pos] * buf[i - pos];
// i - pos is bounded by len:
auto index = ( i - pos ).as_size_t();
rmsWindow[rmsPos] = buf[ index ] * buf[ index ];
rmsSum += rmsWindow[rmsPos];
rmsPos = (rmsPos + 1) % kRMSWindowSize;
@ -551,7 +553,8 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t,
if (gain < mDuckAmountDb)
gain = mDuckAmountDb;
buf[i - pos] *= DB_TO_LINEAR(gain);
// i - pos is bounded by len:
buf[ ( i - pos ).as_size_t() ] *= DB_TO_LINEAR(gain);
}
t->Set((samplePtr)buf, floatSample, pos, len);

View File

@ -487,6 +487,7 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track,
float * inBuffer = new float[inBufferSize];
// mFactor is at most 100-fold so this shouldn't overflow size_t
auto outBufferSize =
(sampleCount)((mFactor * inBufferSize) + 10);
float * outBuffer = new float[outBufferSize];

View File

@ -86,10 +86,15 @@ bool EffectEcho::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames
}
histPos = 0;
histLen = (sampleCount) (mSampleRate * delay);
auto requestedHistLen = (sampleCount) (mSampleRate * delay);
// Guard against extreme delay values input by the user
try {
// Guard against huge delay values from the user.
// Don't violate the assertion in as_size_t
if (requestedHistLen !=
(histLen = static_cast<size_t>(requestedHistLen.as_long_long())))
throw std::bad_alloc{};
history = new float[histLen];
}
catch ( const std::bad_alloc& ) {

View File

@ -1610,7 +1610,8 @@ bool Effect::ProcessTrack(int count,
if (curBlockSize > inputRemaining)
{
// We've reached the last block...set current block size to what's left
curBlockSize = inputRemaining;
// inputRemaining is positive and bounded by a size_t
curBlockSize = inputRemaining.as_size_t();
inputRemaining = 0;
// Clear the remainder of the buffers so that a full block can be passed
@ -1709,10 +1710,12 @@ bool Effect::ProcessTrack(int count,
// so overlay them by shifting the remaining output samples.
else if (curDelay > 0)
{
curBlockSize -= curDelay;
// curDelay is bounded by curBlockSize:
auto delay = curDelay.as_size_t();
curBlockSize -= delay;
for (int i = 0; i < chans; i++)
{
memmove(mOutBufPos[i], mOutBufPos[i] + curDelay, sizeof(float) * curBlockSize);
memmove(mOutBufPos[i], mOutBufPos[i] + delay, sizeof(float) * curBlockSize);
}
curDelay = 0;
}

View File

@ -103,7 +103,8 @@ bool EffectRepair::Process()
const auto s0 = track->TimeToLongSamples(t0);
const auto s1 = track->TimeToLongSamples(t1);
const auto repairStart = (repair0 - s0);
// The difference is at most 2 * 128:
const auto repairStart = (repair0 - s0).as_size_t();
const auto len = s1 - s0;
if (s0 == repair0 && s1 == repair1) {
@ -113,8 +114,12 @@ bool EffectRepair::Process()
break;
}
if (!ProcessOne(count, track,
s0, len, repairStart, repairLen)) {
if (!ProcessOne(count, track, s0,
// len is at most 5 * 128.
len.as_size_t(),
repairStart,
// repairLen is at most 128.
repairLen.as_size_t() )) {
bGoodResult = false;
break;
}

View File

@ -495,7 +495,8 @@ bool EffectTruncSilence::DoRemoval
// Make sure the cross-fade does not affect non-silent frames
if (wt->LongSamplesToTime(blendFrames) > inLength)
{
blendFrames = wt->TimeToLongSamples(inLength);
// Result is not more than blendFrames:
blendFrames = wt->TimeToLongSamples(inLength).as_size_t();
}
// Perform cross-fade in memory

View File

@ -1752,7 +1752,9 @@ int NyquistEffect::GetCallback(float *buffer, int ch,
}
}
long offset = (mCurStart[ch] + start) - mCurBufferStart[ch];
// We have guaranteed above that this is nonnegative and bounded by
// mCurBufferLen[ch]:
auto offset = ( mCurStart[ch] + start - mCurBufferStart[ch] ).as_size_t();
CopySamples(mCurBuffer[ch].ptr() + offset*SAMPLE_SIZE(floatSample), floatSample,
(samplePtr)buffer, floatSample,
len);

View File

@ -393,8 +393,9 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
// find the number of samples for the leading silence
// UNSAFE_SAMPLE_COUNT_TRUNCATION
// -- but used only experimentally as of this writing
// Is there a proof size_t will not overflow?
auto amt = actualDecodeStart - start;
// Is there a proof size_t will not overflow size_t?
// Result is surely nonnegative.
auto amt = (actualDecodeStart - start).as_size_t();
auto cache = make_movable<FFMpegDecodeCache>();
//printf("skipping/zeroing %i samples. - now:%llu (%f), last:%llu, lastlen:%llu, start %llu, len %llu\n",amt,actualDecodeStart, actualDecodeStartdouble, mCurrentPos, mCurrentLen, start, len);
@ -513,14 +514,19 @@ int ODFFmpegDecoder::FillDataFromCache(samplePtr & data, sampleFormat outFormat,
auto nChannels = mDecodeCache[i]->numChannels;
auto samplesHit = (
// Proof that the result is never negative: consider four cases
// of FFMIN and FFMAX choices, and use the if-condition enclosing.
// The result is not more than len.
FFMIN(start+len,mDecodeCache[i]->start+mDecodeCache[i]->len)
- FFMAX(mDecodeCache[i]->start,start)
);
- FFMAX(mDecodeCache[i]->start, start)
).as_size_t();
//find the start of the hit relative to the cache buffer start.
// UNSAFE_SAMPLE_COUNT_TRUNCATION
// -- but used only experimentally as of this writing
// Is there a proof size_t will not overflow?
const auto hitStartInCache = FFMAX(sampleCount{0},start-mDecodeCache[i]->start);
const auto hitStartInCache =
// result is less than mDecodeCache[i]->len:
FFMAX(sampleCount{0},start-mDecodeCache[i]->start).as_size_t();
//we also need to find out which end was hit - if it is the tail only we need to update from a later index.
const auto hitStartInRequest = start < mDecodeCache[i]->start
? len - samplesHit : sampleCount{ 0 };