VMMaker-eem.163 fixes old SoundPlugin bug

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

VMMaker-eem.163 fixes old SoundPlugin bug

Eliot Miranda-2
 
Use of primitiveSoundRecordSamples with a start index other than 1 could corrupt the heap if enough samples were recorded.

Name: VMMaker-eem.163
Author: eem
Time: 22 March 2010, 5:15:57 pm
UUID: 2fa86dda-e18c-48cd-bcac-856504aba8dc
Ancestors: VMMaker-ar.162

SoundPlugin: fix bounds bug in primitiveSoundRecordSamples.  The
call to snd_RecordSamplesIntoAtLength neglected to subtract the
start index from the size of the buffer to be written into.

best
Eliot
Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

David T. Lewis
 
On Mon, Mar 22, 2010 at 05:18:47PM -0700, Eliot Miranda wrote:
>  
> Use of primitiveSoundRecordSamples with a start index other than 1 could
> corrupt the heap if enough samples were recorded.

Nice!

OK, I have to ask. How did you find this bug?

Dave

Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

Josh Gargus


On Mar 22, 2010, at 6:43 PM, David T. Lewis wrote:

>
> On Mon, Mar 22, 2010 at 05:18:47PM -0700, Eliot Miranda wrote:
>>
>> Use of primitiveSoundRecordSamples with a start index other than 1 could
>> corrupt the heap if enough samples were recorded.
>
> Nice!
>
> OK, I have to ask. How did you find this bug?


We've seen intermittent problems from this bug for a while.  Our break came when writing a new back-end for Windows sound-recording resulted in a 100% repeatable crash.  Once we zoned in on the right area,  Eliot's sharp eye picked out the bug almost immediately.

Cheers,
Josh


>
> Dave
>

Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

Bert Freudenberg

On 23.03.2010, at 03:06, Josh Gargus wrote:

>
>
>
> On Mar 22, 2010, at 6:43 PM, David T. Lewis wrote:
>
>>
>> On Mon, Mar 22, 2010 at 05:18:47PM -0700, Eliot Miranda wrote:
>>>
>>> Use of primitiveSoundRecordSamples with a start index other than 1 could
>>> corrupt the heap if enough samples were recorded.
>>
>> Nice!
>>
>> OK, I have to ask. How did you find this bug?
>
>
> We've seen intermittent problems from this bug for a while.  Our break came when writing a new back-end for Windows sound-recording resulted in a 100% repeatable crash.  Once we zoned in on the right area,  Eliot's sharp eye picked out the bug almost immediately.
>
> Cheers,
> Josh

Yay! :)

- Bert -


Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

Eliot Miranda-2
In reply to this post by Eliot Miranda-2
 
Hi All,

    it turns out I jumped the gun on this.  We have been hunting a buffer overrun bug and I mistakenly thought this was it.  In fact our bug was in one of the media codec support libraries we use from a third-party.

I still think the code is confusing, and it looks to me as if it is broken on Mac OS and correct, but confusing, on win32.  Anyone who wants to review this /please/ do.  Here's the original code:

SoundPlugin>>primitiveSoundRecordSamplesInto: buf startingAt: startWordIndex 
"Record a buffer's worth of 16-bit sound samples."
| bufSizeInBytes samplesRecorded |
self primitive: 'primitiveSoundRecordSamples'
parameters: #(WordArray SmallInteger ).

interpreterProxy failed ifFalse:
[bufSizeInBytes := (interpreterProxy slotSizeOf: buf cPtrAsOop) * 4.
interpreterProxy success: (startWordIndex >= 1 and: [startWordIndex - 1 * 2 < bufSizeInBytes])].

interpreterProxy failed ifFalse:
[samplesRecorded := self cCode: 'snd_RecordSamplesIntoAtLength((int)buf, startWordIndex - 1, bufSizeInBytes)'].
^ samplesRecorded asPositiveIntegerObj

My objection in the above is that we do the bounds check above but leave it up to the support code snd_RecordSamplesIntoAtLength to derive the start pointer buf + ((startWordIndex - 1) * 2).  IMO these two belong together.

Now in the Mac code there is no code to subtract (startWordIndex - 1) * 2 from bufSizeInBytes, and so without my fix there could be a buffer overrun:

int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int bufferSizeInBytes) {
    /* if data is available, copy as many sample slices as possible into the
       given buffer starting at the given slice index. do not write past the
       end of the buffer, which is buf + bufferSizeInBytes. return the number
       of slices (not bytes) copied. a slice is one 16-bit sample in mono
       or two 16-bit samples in stereo. */
    int bytesPerSlice = (recordBuffer1.brokenOSXWasMono) ? 2 : ((recordBuffer1.stereo) ? 4 : 2);
    char *nextBuf = (char *) buf + (startSliceIndex * bytesPerSlice);
    char *bufEnd = (char *) buf + bufferSizeInBytes;
    char *src, *srcEnd;
    RecordBuffer recBuf = nil;
    int bytesCopied;

On win32 there is code to do the subtraction.  e.g. looking at the Direct Sound side of the code:

int dx_snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int bufferSizeInBytes) {
  /* if data is available, copy as many sample slices as possible into the
     given buffer starting at the given slice index. do not write past the
     end of the buffer, which is buf + bufferSizeInBytes. return the number
     of slices (not bytes) copied. a slice is one 16-bit sample in mono
     or two 16-bit samples in stereo. */
  int bytesPerSlice = (waveInFormat.nChannels * 2);
  int bytesCopied;
  char *srcPtr, *srcPtr2, *dstPtr;
  HRESULT hRes;
  DWORD srcLen, srcLen2;

...
  /* Figure out how much data we want to copy (don't overflow either the source or destination buffers. */
  bytesCopied = bufferSizeInBytes - (startSliceIndex * bytesPerSlice);
  if(bytesCopied > recBufferAvailable)
    bytesCopied = recBufferAvailable;

  /* Lock the portion of the DirectSound buffer that we will copy data from. */
  hRes = IDirectSoundCaptureBuffer_Lock(lpdRecBuffer,
                    recBufferReadPosition,
                    bytesCopied,
                    (void*)&srcPtr, &srcLen,
                    (void*)&srcPtr2, &srcLen2,
                    0);

So this is an example of a really confusing API.  If instead the API were
snd_RecordSamplesIntoAtLength(int buf, int bufferSizeInBytes)
and the primitive read

SoundPlugin>>primitiveSoundRecordSamplesInto: buf startingAt: startWordIndex 
"Record a buffer's worth of 16-bit sound samples."
| bufSizeInBytes samplesRecorded startByteIndex |
self primitive: 'primitiveSoundRecordSamples'
parameters: #(WordArray SmallInteger ).

interpreterProxy failed ifFalse:
[bufSizeInBytes := (interpreterProxy slotSizeOf: buf cPtrAsOop) * 4.
startByteIndex := startWordIndex - 1 * .
interpreterProxy success: (startWordIndex >= 1 and: [startByteIndex < bufSizeInBytes])].

interpreterProxy failed ifFalse:
[samplesRecorded := self cCode: 'snd_RecordSamplesIntoAtLength((int)buf + startByteIndex, bufSizeInBytes - startByteIndex'].
^ samplesRecorded asPositiveIntegerObj

there would be much less chance for (as the Fat Controller says) confusion and delay.


cheers
Eliot
On Mon, Mar 22, 2010 at 5:18 PM, Eliot Miranda <[hidden email]> wrote:
Use of primitiveSoundRecordSamples with a start index other than 1 could corrupt the heap if enough samples were recorded.

Name: VMMaker-eem.163
Author: eem
Time: 22 March 2010, 5:15:57 pm
UUID: 2fa86dda-e18c-48cd-bcac-856504aba8dc
Ancestors: VMMaker-ar.162

SoundPlugin: fix bounds bug in primitiveSoundRecordSamples.  The
call to snd_RecordSamplesIntoAtLength neglected to subtract the
start index from the size of the buffer to be written into.

best
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

Andreas.Raab
 
+1. The easiest short-term way to address this issue is to move the
computation into the primitive and simply call the support function
always with zero offset. That'll work regardless of whether the support
code subtracts it and regardless of whether we want to change the
interface in the future.

Cheers,
   - Andreas

On 3/29/2010 12:05 PM, Eliot Miranda wrote:

>
>
>
>
> Hi All,
>
>      it turns out I jumped the gun on this.  We have been hunting a
> buffer overrun bug and I mistakenly thought this was it.  In fact our
> bug was in one of the media codec support libraries we use from a
> third-party.
>
> I still think the code is confusing, and it looks to me as if it is
> broken on Mac OS and correct, but confusing, on win32.  Anyone who wants
> to review this /please/ do.  Here's the original code:
>
> SoundPlugin>>primitiveSoundRecordSamplesInto: buf startingAt:
> startWordIndex
> "Record a buffer's worth of 16-bit sound samples."
> | bufSizeInBytes samplesRecorded |
> self primitive: 'primitiveSoundRecordSamples'
> parameters: #(WordArray SmallInteger ).
>
> interpreterProxy failed ifFalse:
> [bufSizeInBytes := (interpreterProxy slotSizeOf: buf cPtrAsOop) * 4.
> interpreterProxy success: (startWordIndex >= 1 and: [startWordIndex - 1
> * 2 < bufSizeInBytes])].
>
> interpreterProxy failed ifFalse:
> [samplesRecorded := self cCode: 'snd_RecordSamplesIntoAtLength((int)buf,
> startWordIndex - 1, bufSizeInBytes)'].
> ^ samplesRecorded asPositiveIntegerObj
>
> My objection in the above is that we do the bounds check above but leave
> it up to the support code snd_RecordSamplesIntoAtLength to derive the
> start pointer buf + ((startWordIndex - 1) * 2).  IMO these two belong
> together.
>
> Now in the Mac code there is no code to subtract (startWordIndex - 1) *
> 2 from bufSizeInBytes, and so without my fix there could be a buffer
> overrun:
>
> int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int
> bufferSizeInBytes) {
>      /* if data is available, copy as many sample slices as possible
> into the
>         given buffer starting at the given slice index. do not write
> past the
>         end of the buffer, which is buf + bufferSizeInBytes. return the
> number
>         of slices (not bytes) copied. a slice is one 16-bit sample in mono
>         or two 16-bit samples in stereo. */
>      int bytesPerSlice = (recordBuffer1.brokenOSXWasMono) ? 2 :
> ((recordBuffer1.stereo) ? 4 : 2);
>      char *nextBuf = (char *) buf + (startSliceIndex * bytesPerSlice);
>      char *bufEnd = (char *) buf + bufferSizeInBytes;
>      char *src, *srcEnd;
>      RecordBuffer recBuf = nil;
>      int bytesCopied;
>
> On win32 there is code to do the subtraction.  e.g. looking at the
> Direct Sound side of the code:
>
> int dx_snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int
> bufferSizeInBytes) {
>    /* if data is available, copy as many sample slices as possible into the
>       given buffer starting at the given slice index. do not write past the
>       end of the buffer, which is buf + bufferSizeInBytes. return the number
>       of slices (not bytes) copied. a slice is one 16-bit sample in mono
>       or two 16-bit samples in stereo. */
>    int bytesPerSlice = (waveInFormat.nChannels * 2);
>    int bytesCopied;
>    char *srcPtr, *srcPtr2, *dstPtr;
>    HRESULT hRes;
>    DWORD srcLen, srcLen2;
>
> ...
>    /* Figure out how much data we want to copy (don't overflow either
> the source or destination buffers. */
>    bytesCopied = bufferSizeInBytes - (startSliceIndex * bytesPerSlice);
>    if(bytesCopied > recBufferAvailable)
>      bytesCopied = recBufferAvailable;
>
>    /* Lock the portion of the DirectSound buffer that we will copy data
> from. */
>    hRes = IDirectSoundCaptureBuffer_Lock(lpdRecBuffer,
>                      recBufferReadPosition,
>                      bytesCopied,
>                      (void*)&srcPtr, &srcLen,
>                      (void*)&srcPtr2, &srcLen2,
>                      0);
>
> So this is an example of a really confusing API.  If instead the API were
> snd_RecordSamplesIntoAtLength(int buf, int bufferSizeInBytes)
> and the primitive read
>
> SoundPlugin>>primitiveSoundRecordSamplesInto: buf startingAt:
> startWordIndex
> "Record a buffer's worth of 16-bit sound samples."
> | bufSizeInBytes samplesRecorded startByteIndex |
> self primitive: 'primitiveSoundRecordSamples'
> parameters: #(WordArray SmallInteger ).
>
> interpreterProxy failed ifFalse:
> [bufSizeInBytes := (interpreterProxy slotSizeOf: buf cPtrAsOop) * 4.
> startByteIndex := startWordIndex - 1 * .
> interpreterProxy success: (startWordIndex >= 1 and: [startByteIndex <
> bufSizeInBytes])].
>
> interpreterProxy failed ifFalse:
> [samplesRecorded := self cCode: 'snd_RecordSamplesIntoAtLength((int)buf
> + startByteIndex, bufSizeInBytes - startByteIndex'].
> ^ samplesRecorded asPositiveIntegerObj
>
> there would be much less chance for (as the Fat Controller says)
> confusion and delay.
>
>
> cheers
> Eliot
> On Mon, Mar 22, 2010 at 5:18 PM, Eliot Miranda <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Use of primitiveSoundRecordSamples with a start index other than 1
>     could corrupt the heap if enough samples were recorded.
>
>     Name: VMMaker-eem.163
>     Author: eem
>     Time: 22 March 2010, 5:15:57 pm
>     UUID: 2fa86dda-e18c-48cd-bcac-856504aba8dc
>     Ancestors: VMMaker-ar.162
>
>     SoundPlugin: fix bounds bug in primitiveSoundRecordSamples.  The
>     call to snd_RecordSamplesIntoAtLength neglected to subtract the
>     start index from the size of the buffer to be written into.
>
>     best
>     Eliot
>
>
Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

David T. Lewis
 
That sounds good. And as long as you both are looking at
snd_RecordSamplesIntoAtLength(), can you please help me fix the
broken method signatures? This is to resolve pointer-as-int problems
that prevent sound from working on 64-bit platforms.

I have attached the updated platforms/Cross/plugins/SoundPlugin/SoundPlugin.h
file that needs to be checked in to Subversion (Andreas, can do this?).

I don't have Windows platform patches, but the updates are straightforward,
and the unix platforms patches are attached here:
  http://lists.squeakfoundation.org/pipermail/vm-dev/2009-December/003586.html

The original Mantis issue is:
  http://bugs.squeak.org/view.php?id=7103

The VMMaker patches are already in place.

Thanks!

Dave

On Mon, Mar 29, 2010 at 12:20:09PM -0700, Andreas Raab wrote:

>
> +1. The easiest short-term way to address this issue is to move the
> computation into the primitive and simply call the support function
> always with zero offset. That'll work regardless of whether the support
> code subtracts it and regardless of whether we want to change the
> interface in the future.
>
> Cheers,
>   - Andreas
>
> On 3/29/2010 12:05 PM, Eliot Miranda wrote:
> >
> >
> >
> >
> >Hi All,
> >
> >     it turns out I jumped the gun on this.  We have been hunting a
> >buffer overrun bug and I mistakenly thought this was it.  In fact our
> >bug was in one of the media codec support libraries we use from a
> >third-party.
> >
> >I still think the code is confusing, and it looks to me as if it is
> >broken on Mac OS and correct, but confusing, on win32.  Anyone who wants
> >to review this /please/ do.  Here's the original code:
> >
> >SoundPlugin>>primitiveSoundRecordSamplesInto: buf startingAt:
> >startWordIndex
> >"Record a buffer's worth of 16-bit sound samples."
> >| bufSizeInBytes samplesRecorded |
> >self primitive: 'primitiveSoundRecordSamples'
> >parameters: #(WordArray SmallInteger ).
> >
> >interpreterProxy failed ifFalse:
> >[bufSizeInBytes := (interpreterProxy slotSizeOf: buf cPtrAsOop) * 4.
> >interpreterProxy success: (startWordIndex >= 1 and: [startWordIndex - 1
> >* 2 < bufSizeInBytes])].
> >
> >interpreterProxy failed ifFalse:
> >[samplesRecorded := self cCode: 'snd_RecordSamplesIntoAtLength((int)buf,
> >startWordIndex - 1, bufSizeInBytes)'].
> >^ samplesRecorded asPositiveIntegerObj
> >
> >My objection in the above is that we do the bounds check above but leave
> >it up to the support code snd_RecordSamplesIntoAtLength to derive the
> >start pointer buf + ((startWordIndex - 1) * 2).  IMO these two belong
> >together.
> >
> >Now in the Mac code there is no code to subtract (startWordIndex - 1) *
> >2 from bufSizeInBytes, and so without my fix there could be a buffer
> >overrun:
> >
> >int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int
> >bufferSizeInBytes) {
> >     /* if data is available, copy as many sample slices as possible
> >into the
> >        given buffer starting at the given slice index. do not write
> >past the
> >        end of the buffer, which is buf + bufferSizeInBytes. return the
> >number
> >        of slices (not bytes) copied. a slice is one 16-bit sample in mono
> >        or two 16-bit samples in stereo. */
> >     int bytesPerSlice = (recordBuffer1.brokenOSXWasMono) ? 2 :
> >((recordBuffer1.stereo) ? 4 : 2);
> >     char *nextBuf = (char *) buf + (startSliceIndex * bytesPerSlice);
> >     char *bufEnd = (char *) buf + bufferSizeInBytes;
> >     char *src, *srcEnd;
> >     RecordBuffer recBuf = nil;
> >     int bytesCopied;
> >
> >On win32 there is code to do the subtraction.  e.g. looking at the
> >Direct Sound side of the code:
> >
> >int dx_snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int
> >bufferSizeInBytes) {
> >   /* if data is available, copy as many sample slices as possible into the
> >      given buffer starting at the given slice index. do not write past the
> >      end of the buffer, which is buf + bufferSizeInBytes. return the
> >      number
> >      of slices (not bytes) copied. a slice is one 16-bit sample in mono
> >      or two 16-bit samples in stereo. */
> >   int bytesPerSlice = (waveInFormat.nChannels * 2);
> >   int bytesCopied;
> >   char *srcPtr, *srcPtr2, *dstPtr;
> >   HRESULT hRes;
> >   DWORD srcLen, srcLen2;
> >
> >...
> >   /* Figure out how much data we want to copy (don't overflow either
> >the source or destination buffers. */
> >   bytesCopied = bufferSizeInBytes - (startSliceIndex * bytesPerSlice);
> >   if(bytesCopied > recBufferAvailable)
> >     bytesCopied = recBufferAvailable;
> >
> >   /* Lock the portion of the DirectSound buffer that we will copy data
> >from. */
> >   hRes = IDirectSoundCaptureBuffer_Lock(lpdRecBuffer,
> >                     recBufferReadPosition,
> >                     bytesCopied,
> >                     (void*)&srcPtr, &srcLen,
> >                     (void*)&srcPtr2, &srcLen2,
> >                     0);
> >
> >So this is an example of a really confusing API.  If instead the API were
> >snd_RecordSamplesIntoAtLength(int buf, int bufferSizeInBytes)
> >and the primitive read
> >
> >SoundPlugin>>primitiveSoundRecordSamplesInto: buf startingAt:
> >startWordIndex
> >"Record a buffer's worth of 16-bit sound samples."
> >| bufSizeInBytes samplesRecorded startByteIndex |
> >self primitive: 'primitiveSoundRecordSamples'
> >parameters: #(WordArray SmallInteger ).
> >
> >interpreterProxy failed ifFalse:
> >[bufSizeInBytes := (interpreterProxy slotSizeOf: buf cPtrAsOop) * 4.
> >startByteIndex := startWordIndex - 1 * .
> >interpreterProxy success: (startWordIndex >= 1 and: [startByteIndex <
> >bufSizeInBytes])].
> >
> >interpreterProxy failed ifFalse:
> >[samplesRecorded := self cCode: 'snd_RecordSamplesIntoAtLength((int)buf
> >+ startByteIndex, bufSizeInBytes - startByteIndex'].
> >^ samplesRecorded asPositiveIntegerObj
> >
> >there would be much less chance for (as the Fat Controller says)
> >confusion and delay.
> >
> >
> >cheers
> >Eliot
> >On Mon, Mar 22, 2010 at 5:18 PM, Eliot Miranda <[hidden email]
> ><mailto:[hidden email]>> wrote:
> >
> >    Use of primitiveSoundRecordSamples with a start index other than 1
> >    could corrupt the heap if enough samples were recorded.
> >
> >    Name: VMMaker-eem.163
> >    Author: eem
> >    Time: 22 March 2010, 5:15:57 pm
> >    UUID: 2fa86dda-e18c-48cd-bcac-856504aba8dc
> >    Ancestors: VMMaker-ar.162
> >
> >    SoundPlugin: fix bounds bug in primitiveSoundRecordSamples.  The
> >    call to snd_RecordSamplesIntoAtLength neglected to subtract the
> >    start index from the size of the buffer to be written into.
> >
> >    best
> >    Eliot
> >
> >

SoundPlugin.h (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

johnmci
In reply to this post by Eliot Miranda-2
 
You are aware (no?) that this code was abandon in 2005 and replaced by 

sqMacUnixInterfaceSound.c & sqUnixSoundMacOSX.c 

The typedefs are wrong for 64bit work, but I've replace the logic in Squeak V5 anyway. 

 sqInt sound_RecordSamplesIntoAtLength(sqInt buf, sqInt startSliceIndex, sqInt bufferSizeInBytes)
{
  if (input)
    {
      if (Buffer_avail(input->buffer) >= (512 * DeviceFrameSize))
{
  sqInt    start= startSliceIndex * SqueakFrameSize / 2;
  UInt32 count= min(input->cvtBufSize, bufferSizeInBytes - start);
  if (kAudioHardwareNoError == AudioConverterFillBuffer(input->converter, bufferDataProc, input,
&count, (char *)buf + start))
    return count / (SqueakFrameSize / 2) / input->channels;
}
      return 0;
    }
  success(false);
  return 0;
}

sqInt snd_RecordSamplesIntoAtLength(usqInt *buf, sqInt startSliceIndex, sqInt bufferSizeInBytes)
{
  return sound_RecordSamplesIntoAtLength(buf, startSliceIndex, bufferSizeInBytes);
}


Version 5 of Squeak macintosh VM uses 

- (sqInt) snd_RecordSamplesIntoAtLength: (char*) arrayIndex startSliceIndex: (usqInt) startSliceIndex bufferSizeInBytes: (usqInt) bufferSizeInBytes {


usqInt count;


if (!self.inputAudioQueue) 
return interpreterProxy->primitiveFail();
if (startSliceIndex > bufferSizeInBytes) 
return interpreterProxy->primitiveFail();

usqInt    start= startSliceIndex * SqueakFrameSize / 2;
soundAtom *atom = [self.soundInQueue returnOldest];
if (atom == nil
return 0;
if (bufferSizeInBytes-start >= atom.byteCount && atom.startOffset == 0) {
atom = [self.soundInQueue returnAndRemoveOldest];
memcpy(arrayIndex+start,atom.data,atom.byteCount);
count= MIN(atom.byteCount, bufferSizeInBytes - start);
[atom release];
return count / (SqueakFrameSize / 2) / self.inputChannels;
} else {
count= MIN(atom.byteCount-atom.startOffset, bufferSizeInBytes - start);
memcpy(arrayIndex+start,atom.data+atom.startOffset,count);
atom.startOffset = atom.startOffset + (count);
if (atom.startOffset == atom.byteCount) {
atom = [self.soundInQueue returnAndRemoveOldest]; //ignore now it's empty
[atom release];
}
return count / (SqueakFrameSize / 2) / self.inputChannels;
}


}






On 2010-03-29, at 12:05 PM, Eliot Miranda wrote:

Now in the Mac code there is no code to subtract (startWordIndex - 1) * 2 from bufSizeInBytes, and so without my fix there could be a buffer overrun:

int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int bufferSizeInBytes) {
    /* if data is available, copy as many sample slices as possible into the
       given buffer starting at the given slice index. do not write past the
       end of the buffer, which is buf + bufferSizeInBytes. return the number
       of slices (not bytes) copied. a slice is one 16-bit sample in mono
       or two 16-bit samples in stereo. */
    int bytesPerSlice = (recordBuffer1.brokenOSXWasMono) ? 2 : ((recordBuffer1.stereo) ? 4 : 2);
    char *nextBuf = (char *) buf + (startSliceIndex * bytesPerSlice);
    char *bufEnd = (char *) buf + bufferSizeInBytes;
    char *src, *srcEnd;
    RecordBuffer recBuf = nil;
    int bytesCopied;

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================





smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: VMMaker-eem.163 fixes old SoundPlugin bug

johnmci
In reply to this post by David T. Lewis
 
Ok, well I had to make some mods to the 4.x.x series of macintosh VMs to fix the sound recording after eliot's patchs
Also I'll check in the changes you listed.


On 2010-03-29, at 5:18 PM, David T. Lewis wrote:

> That sounds good. And as long as you both are looking at
> snd_RecordSamplesIntoAtLength(), can you please help me fix the
> broken method signatures? This is to resolve pointer-as-int problems
> that prevent sound from working on 64-bit platforms.
>
> I have attached the updated platforms/Cross/plugins/SoundPlugin/SoundPlugin.h
> file that needs to be checked in to Subversion (Andreas, can do this?).
>
> I don't have Windows platform patches, but the updates are straightforward,
> and the unix platforms patches are attached here:
>  http://lists.squeakfoundation.org/pipermail/vm-dev/2009-December/003586.html
>
> The original Mantis issue is:
>  http://bugs.squeak.org/view.php?id=7103
>
> The VMMaker patches are already in place.
>
> Thanks!
>
> Dave
--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================





smime.p7s (3K) Download Attachment