在 2021年10月7日 +0800 14:18,Sven Neumann via SoX-devel <sox-devel@lists.sourceforge.net>,写道: > Hi, > > thanks for pointing me to > https://sourceforge.net/p/sox/mailman/message/37325794/. This is exactly the > problem I am trying to solve. > > I am somewhat surprised that we can actually recover the whole buffer after a > seek and write because the memory stream maintains a null byte after the > data. I was assuming that this means that we can not simply recover by > seeking back to the end of the buffer because one byte would have been > overwritten by that terminator byte. I tried what you suggested (code > attached), and it seems that the terminating null byte is not moved on a seek > operation, but only when the file descriptor is closed. > > Of course it would be desirable to have a proper WAV header even for streams > opened with sox_open_memstream_write(). I can prepare a fix that introduces a > seek back, but I guess I would have to do something similar for all formats > that seek in the output buffer. Before I start to work on that I would like > to get approval from the maintainer that this is the right approach. Yes, I guess there are lots of works to do related to this seek opt. Let me know if you need any help.
Regards, SunZhenliang > > > Regards, > Sven > > > From: Sun Zhenliang <hisunzhenli...@outlook.com> > Sent: 07 October 2021 04:24 > To: sox-devel@lists.sourceforge.net <sox-devel@lists.sourceforge.net> > Subject: Re: [SoX-devel] [PATCH] formats: disallow seeking in dynamic memory > buffers > > 在 2021年10月7日 +0800 05:35,Sven Neumann via SoX-devel > <sox-devel@lists.sourceforge.net>,写道: > Hi, > > in one of our internal applications we are using SoX (the 14.4.2+git20190427 > version from Ubuntu) to convert from a variety of audio formats to the WAV > file format. We observed that the tests for the conversion occasionally > failed and over the last days I found time to dig deeper into this. > > We are using sox_open_memstream_write() to write to a dynamically allocated > in-memory stream. In our tests sometimes the size of the resulting WAV buffer > would have the expected size, sometimes it would be 44 bytes, the size of the > WAV header. Valgrind told me that the behavior of is_seekable() in formats.c > depends on uninitialized memory. In your git repository I found a fix for > this: > > commit bb38934e11035c8fab141f70dabda3afdd17da36 > Author: Mans Rullgard <m...@mansr.com> > Date: Tue Aug 4 17:19:49 2020 +0100 > > format: improve is_seekable() test > > Streams opened with fmemopen() do not have an underlying file descriptor, > so the fstat() will fail, and a random result is returned. > > A simpler method that works regardless of file type is to call fseek() > and check if it reports success. > > Suggested by Stefan Sauer <enso...@google.com>. > > > Now with this fix applied valgrind was happy, however now our conversion from > MP3 to WAV would always result in only 44 bytes, as read from the > buffer_size_ptr location passed to sox_open_memstream_write(). It turns out > that with above change the undefined behavior is fixed for streams created > with open_memstream() and is_seekable() will now reliably returns sox_true > for such streams. This allows the WAV writer code to do an fseek() to the > start of the stream followed by a write of the WAV header with correct length > information. However such a seek followed by a write causes the dynamically > allocated memory stream to be truncated. Thus after calling sox_close() the > size reported for the stream will be 44 bytes, that's not what we want. > Unfortunately we can not simply fix this by reporting the full buffer size as > the buffer will actually have been truncated, and a trailing null byte is > appended after the WAV header. It looks like we can indeed not seek and fix > data in a dynamically allocated stream. Thus I am attaching a patch that > changes the code in formats.c to set ft->seekable to false for streams opened > with open_memstream(). With this change applied on top of the improvement for > the is_seekable() test, our tests pass reliably and valgrind seems happy as > well. > > I am attaching the patch here, please consider it for inclusion. I am also > attaching a simple test application that writes to a stream, seeks to the > front and performs another write. The output of this program illustrates that > the buffer is truncated: > > buf = `hello', size = 5 > buf = `hello, world', size = 12 > buf = `heyho', size = 5 > Bug mentioned https://sourceforge.net/p/sox/mailman/message/37325794/. > > It is possible to fix the whole data. From my test to open_memstream(), the > dynamically allocated memory would not be free before the ft->fp was closed. > The data written is still there if it’s not covered by other write opt. > > In this WAV issue, the seek opt is just in sox_close() to rewrite header, > which > is the end of transcoding and will not cover the data area. We can just > ftell() > to get the end of file before the fseek and seek back to the end after > rewriting. > > Output with ftell opt: > buf = `hello', size = 5 > buf = `hello, world', size = 12 > buf = `heyho, world', size = 12 > > As for other formats, the situation may be different from WAV and needs > specific > analysis. > > > > Regards, > Sven > > > > > _______________________________________________ > SoX-devel mailing list > SoX-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/sox-devel > > _______________________________________________ > SoX-devel mailing list > SoX-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/sox-devel
_______________________________________________ SoX-devel mailing list SoX-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sox-devel