Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stb_vorbis doesn't build as C++ #1

Closed
DanielGibson opened this issue Feb 4, 2024 · 7 comments
Closed

stb_vorbis doesn't build as C++ #1

DanielGibson opened this issue Feb 4, 2024 · 7 comments

Comments

@DanielGibson
Copy link

DanielGibson commented Feb 4, 2024

So far stb_vorbis.c could be built as C++ (I usually rename it to stb_vorbis.h and use it more or less like the other stb libs).
With the changes in this repo that doesn't work anymore

I haven't tried with MSVC, but GCC (g++) gives errors like this:

dhewm3/neo/sound/stb_vorbis.h:3790:54: error: cannot convert ‘uint8*’ {aka ‘unsigned char*’} to ‘void**’
 3790 |                    if (c->sparse) setup_temp_free(f, lengths, c->entries);
      |                                                      ^~~~~~~
      |                                                      |
      |                                                      uint8* {aka unsigned char*}
In file included from dhewm3/neo/sound/snd_decoder.cpp:36:
dhewm3/neo/sound/stb_vorbis.h:990:45: note:   initializing argument 2 of ‘void setup_temp_free(vorb*, void**, int)’
  990 | static void setup_temp_free(vorb *f, void **_p, int sz)
      |                                      ~~~~~~~^~

This happens in several other places where setup_temp_free() is called, and the issue is always that a uint8 * value is passed as second argument of setup_temp_free() which expects a void **.

I'm not sure how this code can work anywhere (even when compiled as C, which might be more tolerant with the implicit conversion) - uint8 * lengths gets the return value of setup_temp_malloc(whatever) assigned - and as far as I understand, those results are supposed to be passed dereferenced to setup_temp_free(), so setup_temp_free() can set the pointer to NULL (void *p = *_p; *_p = NULL;). So the example shown above should probably look like if (c->sparse) setup_temp_free(f, &lengths, c->entries);.

Changing the code to make the compiler happy would be easy enough, but TBH with errors like this I don't trust the changes that changed setup_temp_free() to take a pointer to a pointer enough to use them at all, and I don't have the time to review them thoroughly enough to figure out why this code apparently worked for whoever wrote it, despite appearing to be plainly wrong.

Update: Oh by the way, thanks a lot for maintaining this repo! :)

@DanielGibson
Copy link
Author

Oh, looking at git blame, the problem seems to be that the PR introducing the void ** argument (commit 2ec4a48) was independent of the one adding the setup_temp_free() calls in question (commit 684ae83) - that explains how this happened, of course.

Still makes me a bit weary of how well all these fixes merged together interact with each other..

@NBickford-NV
Copy link
Owner

Thank you for the issue! I'll put in a fix right now, and add some testing to make sure everything builds.

@DanielGibson
Copy link
Author

Awesome, thanks!
This fork might be useful: https://github.com/sezero/stb/tree/stb_vorbis-sezero
It contains lots of vorbis tests

NBickford-NV added a commit that referenced this issue Feb 4, 2024
…different terminology -- one correctly deallocated temp memory, while the other added more deallocations in error cases. The fix is to merge the terminology of one with the new lines of code in the other.
NBickford-NV added a commit that referenced this issue Feb 4, 2024
…arious issues that came up in the tests; the worst is probably an out-of-bounds write when stb_sprintf's second argument is 0. (See issue #1).

Details:

deprecated/stb.h:
* Fix crash when computing perfect hashes over a table of size 1, due to stb_log2_floor returning -1 for an input of 1 when it should only return -1 for an input of 0.
* Fix undefined behavior in call to strcpy_s: The size term must be the size of the destination buffer; if it's too large, it's UB (and crashes MSVC, which assumes it can copy in chunks that large).

stb_sprintf.h:
* Add STBSP__ASAN definition
* Fix OOB write in the case where `count == 0`.

tests/grid_reachability.c:
* Fix printf specifier: %d -> %zu for size_t

tests/stb.c:
* Fix printf specifier: %d -> %zu for size_t
* Turn off code using STUA, as this does not appear to be present in current versions of stb.
* Change from `__asm int 3;` to `__debugbreak()`, as the former syntax is not supported in VS 2022.

test/test_ds.c:
* Fix segfault: the issue was that in `arrins(temp, arrlen(temp), 'b')`, `arrins` is a macro, so `arrlen(temp)` gets inserted into multiple places; as a result, one part of the expanded macro used a size of 1 and the other used a size of 2, leading to a write at a bad index.

test/test_sprintf.c:
* Fix header for ssize_t on Windows

tests/test_vorbis.c:
* Look for sketch008.ogg in a local directory rather than hardcoding the path to it.
@NBickford-NV
Copy link
Owner

Thank you! I think I've got a fix for it in 2e9cec9 . That fork's perfect; I'm going to see if I can import its tests and run through all of those and add a simple vorbis fuzzer before closing this issue.

On the testing side, I've added a CMake project with an initial go at building the various projects in tests/; that currently targets the top-level files in tests/, and I'm hoping to add the ones within subfolders as well.

That wound up finding a couple of issues, which I think I've fixed in 5ebf39c. The biggest one is that a line like

stbsp_snprintf(buf, 0, "7 chars");

would make stb_sprintf write a null terminator to buf[-1].

@NBickford-NV
Copy link
Owner

The other issue is that stb_c_lexer_fuzzer.c pretty much immediately finds a crash (a file that consists entirely of an identifier will make it read past the end). That's not good.

NBickford-NV added a commit that referenced this issue Feb 4, 2024
…igate resource exhaustion attack by checking size against length of stream.
@NBickford-NV
Copy link
Owner

As of ca527d1, this fork now has the tests from sezero's fork, and a vorbis fuzzer!

Good news:

I'm going to go ahead and close this issue, since I think the original issue (compilation) has now been fixed. Thanks again for reporting this!

@DanielGibson
Copy link
Author

Great work, thank you! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants