ok with me

On 2023/04/03 16:02, Nam Nguyen wrote:
> wav gsm playback and encoding is broken because the wav.c patch to avoid
> division by 0 introduced a regression. Debian has a fix for an older
> version of sox from Helmut Grohne <helmut () subdivi ! de>. This patch
> is from Steffen Nurpmeso <steffen () sdaoden ! eu> who applied it
> against git. I added a tweak to not recalculate wave->numSamples for wav
> gsm files, which is where division by 0 happens. Apparently, gsm has
> variable bits_per_sample, so 0 is an acceptable value.
> 
> Steffen's diff: https://marc.info/?l=oss-security&m=167882517702862&w=2
> tweak: https://marc.info/?l=oss-security&m=168026419507884&w=2
> 
> Test cases
> ----------
> With this diff these two test cases pass.
> 
> Test case 1: convert /dev/null to bug.wav (wav gsm) and then convert
> bug.wav to fail.wav.
> 
> This test case is expected to pass.
> 
> incorrect output:
> --8<---------------cut here---------------start------------->8---
> $ sox -t raw -r 44100 -e signed-integer -b 8 /dev/null -t wav -e 
> gsm-full-rate \
> bug.wav $ sox bug.wav fail.wav
> sox FAIL formats: can't open input file `bug.wav': WAV file bits per sample 
> is zero
> --8<---------------cut here---------------end--------------->8---
> 
> correct output (which this provides):
> --8<---------------cut here---------------start------------->8---
> $ sox -t raw -r 44100 -e signed-integer -b 8 /dev/null -t wav -e 
> gsm-full-rate \
> bug.wav $ sox bug.wav fail.wav
> $ file fail.wav
> fail.wav: RIFF (little-endian) data, WAVE audio, GSM 6.10, mono 44100 Hz
> --8<---------------cut here---------------end--------------->8---
> 
> Test case 2: convert flac to wav gsm. then, convert wav gsm to wav gsm.
> 
> This test case is expected to pass.
> --8<---------------cut here---------------start------------->8---
> $ sox -t flac -r 44100 -e signed-integer -b 16 song.flac -t wav -e 
> gsm-full-rate \
> ok.wav $ sox ok.wav ok2.wav
> --8<---------------cut here---------------end--------------->8---
> 
> Feedback is welcome. OK?
> 
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/audio/sox/Makefile,v
> retrieving revision 1.76
> diff -u -p -u -p -r1.76 Makefile
> --- Makefile  22 Feb 2023 16:27:38 -0000      1.76
> +++ Makefile  3 Apr 2023 22:51:32 -0000
> @@ -5,7 +5,7 @@ V=            14.4.2pl20210509
>  GIT_V=               14.4.3git
>  DISTNAME=    sox-${V}
>  SHARED_LIBS +=       sox 4.1 # 3.0
> -REVISION=    0
> +REVISION=    1
>  
>  CATEGORIES=  audio
>  HOMEPAGE=    http://sox.sourceforge.net/
> Index: patches/patch-src_wav_c
> ===================================================================
> RCS file: /cvs/ports/audio/sox/patches/patch-src_wav_c,v
> retrieving revision 1.3
> diff -u -p -u -p -r1.3 patch-src_wav_c
> --- patches/patch-src_wav_c   22 Feb 2023 15:03:03 -0000      1.3
> +++ patches/patch-src_wav_c   3 Apr 2023 22:51:32 -0000
> @@ -1,14 +1,22 @@
>  https://marc.info/?l=oss-security&m=167571683504082&w=2
>  
> +unbreak wav gsm
> +see:
> +https://marc.info/?l=oss-security&m=167882517702862&w=2
> +https://marc.info/?l=oss-security&m=168026419507884&w=2
> +
>  Index: src/wav.c
>  --- src/wav.c.orig
>  +++ src/wav.c
> -@@ -654,6 +654,12 @@ static int wav_read_fmt(sox_format_t *ft, uint32_t len
> +@@ -654,6 +654,15 @@ static int wav_read_fmt(sox_format_t *ft, uint32_t len
>       if (err)
>           return SOX_EOF;
>   
> -+    if (wav->bitsPerSample == 0)
> -+    {
> ++    if (wav->bitsPerSample == 0
> ++#ifdef HAVE_LIBGSM
> ++            && wav->formatTag != WAVE_FORMAT_GSM610
> ++#endif
> ++    ){
>  +        lsx_fail_errno(ft, SOX_EHDR, "WAV file bits per sample is zero");
>  +        return SOX_EOF;
>  +    }
> @@ -16,3 +24,68 @@ Index: src/wav.c
>       /* non-PCM formats except alaw and mulaw formats have extended fmt 
> chunk.
>        * Check for those cases.
>        */
> +@@ -963,7 +972,11 @@ static int startread(sox_format_t *ft)
> + #endif
> +     }
> + 
> +-    if (!wav->numSamples)
> ++    if (!wav->numSamples
> ++#ifdef HAVE_LIBGSM
> ++            && wav->formatTag != WAVE_FORMAT_GSM610
> ++#endif
> ++    )
> +         wav->numSamples = div_bits(qwDataLength, 
> ft->encoding.bits_per_sample)
> +             / ft->signal.channels;
> + 
> +@@ -1348,8 +1361,10 @@ static int wavwritehdr(sox_format_t * ft, int second_h
> +         (dwSamplesWritten + wSamplesPerBlock - 1) / wSamplesPerBlock;
> +     dwDataLength = blocksWritten * wBlockAlign;
> + 
> ++#ifdef HAVE_LIBGSM
> +     if (wFormatTag == WAVE_FORMAT_GSM610)
> +         dwDataLength = (dwDataLength+1) & ~1u; /* round up to even */
> ++#endif
> + 
> +     if (wFormatTag == WAVE_FORMAT_PCM && (wBitsPerSample > 16 || wChannels 
> > 2)
> +         && strcmp(ft->filetype, "wavpcm")) {
> +@@ -1444,9 +1459,11 @@ static int wavwritehdr(sox_format_t * ft, int second_h
> +             lsx_writew(ft, (uint16_t)(lsx_ms_adpcm_i_coef[i][1]));
> +         }
> +         break;
> ++#ifdef HAVE_LIBGSM
> +         case WAVE_FORMAT_GSM610:
> +         lsx_writew(ft, wSamplesPerBlock);
> +         break;
> ++#endif
> +         default:
> +         break;
> +     }
> +@@ -1554,7 +1571,9 @@ static int stopwrite(sox_format_t * ft)
> + 
> +         /* Add a pad byte if the number of data bytes is odd.
> +            See wavwritehdr() above for the calculation. */
> ++#ifdef HAVE_LIBGSM
> +         if (wav->formatTag != WAVE_FORMAT_GSM610)
> ++#endif
> +           lsx_padbytes(ft, (size_t)((wav->numSamples + wav->samplesPerBlock 
> - 1)/wav->samplesPerBlock*wav->blockAlign) % 2);
> + 
> +         free(wav->packet);
> +@@ -1594,6 +1613,7 @@ static int seek(sox_format_t * ft, uint64_t offset)
> + 
> +   if (ft->encoding.bits_per_sample & 7)
> +     lsx_fail_errno(ft, SOX_ENOTSUP, "seeking not supported with this 
> encoding");
> ++#ifdef HAVE_LIBGSM
> +   else if (wav->formatTag == WAVE_FORMAT_GSM610) {
> +     int alignment;
> +     size_t gsmoff;
> +@@ -1613,7 +1633,9 @@ static int seek(sox_format_t * ft, uint64_t offset)
> +           new_offset += (wav->samplesPerBlock - alignment);
> +       wav->numSamples = ft->signal.length - (new_offset / 
> ft->signal.channels);
> +     }
> +-  } else {
> ++  }
> ++#endif /* HAVE_LIBGSM */
> ++  else {
> +     double wide_sample = offset - (offset % ft->signal.channels);
> +     double to_d = wide_sample * ft->encoding.bits_per_sample / 8;
> +     off_t to = to_d;
> 

Reply via email to