-
Notifications
You must be signed in to change notification settings - Fork 103
[Jellyfin] Rework buffer into C++ class #120
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
Conversation
4fa40c1
to
825c98a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[dimtrylyzo:] This is the only thing I can extract with such strict requirements in your repo.
There are also fixes for seemingly pre-existing issues like 026b744 (in the linked example, at first glance it appears like it only needs a polished commit message).
src/SubtitleOctopus.cpp
Outdated
float* buf = (float*)buffer_resize(&m_blend, sizeof(float) * width * height * 4, 0); | ||
float* buf = (float*)m_blend.take(sizeof(float) * width * height * 4, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pre-existing issue (so new commit to fix), but this line has potentially a big issue:
Afaict there's no prior checks for this and the multiplications for the new_size
parameter can overflow the bounds of int
, which is in itself already undefined behaviour, but if your lucky only truncates. Worse though, the buffer is later accessed by values recalculated from width
and height
, so if the multiplication here overflowed (and the overflow itself doesn't blow up), an out-of-bound write happens either blowing up or corrupting some other memory.
Is ReusableBuffer
ever used for something else than an float-RGBA canvas alter down the line in jellyfin-patches? If not it's probably best to pass width
, height
and member_size
as separate size_t
-type values to the resize function and do all the overflow checking inside the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but if your lucky only truncates.
No, we will definitely get an overflow in the loop.
Is
ReusableBuffer
ever used for something else than an float-RGBA canvas alter down the line in jellyfin-patches?
ReusableBuffer
is only used by blend renderer as a frame buffer.
If not it's probably best to pass
width
,height
andmember_size
as separatesize_t
-type values to the resize function and do all the overflow checking inside the function.
I like that idea, but maybe do it in a future refactor?
member_size
becomes unnecessary if I replace void
with float
.
At the same time, having something like std::vector
would help for memory management in the future.
UPD:
As a quick fix, we could add the maximum buffer size, say 8K_resolution * sizeof(float) * 4
, and return NULL
if new_size
is greater than this limit.
UPD2:
I chose the more preferable (your) way.
#124
#ifdef __EMSCRIPTEN__ | ||
#include "./SubOctpInterface.cpp" | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, unrelated to the buffer refactor.
Second: Are there some tests or some other use for compiling this without emscripten? If not, I see no use in adding the guard in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It allows you to compile the file alone, iirc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, but is there even any useful standalone program or tests you can build with this file? For some reason SubtitleOctopus.cpp has a main function, but all it does is to immediately exit, which is not remotely useful.
If there is no use for compiling it without emscripten, then the guard is not necessary and even misleading as it suggest there is some use in compiling it without emscripten.
If, on the other hand, there are some hidden tests which use this standalone we should integrate them into our CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just use g++ SubtitleOctopus.cpp
to see if it compiles without having to run the full build process.
This has the same purpose:
JavascriptSubtitlesOctopus/src/SubtitleOctopus.cpp
Lines 13 to 18 in de8888f
#ifdef __EMSCRIPTEN__ | |
#include <emscripten.h> | |
#else | |
// make IDE happy | |
#define emscripten_get_now() 0.0 | |
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make -C src
would also do, but if it’s already partly guarded anyway .. oh well. At least mention in the commit-message that this is only to quickly check for compiler warnings/errors and there’s no use to the compiled program or otheriwse.
Yes, that error could theoretically happen even without |
de8888f
to
eac55b6
Compare
The commits |
Atm For just refactoring the struct into a class, hte (initial) scope of this PR, I think just the refactoring itself, with a renaming of |
As here: JavascriptSubtitlesOctopus/src/SubtitleOctopus.cpp Lines 347 to 348 in a5afc83
Or it could be an underscore at the end. Originally I wanted to add the size method (will conflict with the size data member). But now it may be redundant if the size is saved by the caller of ensure_size .
I am currently driven by this idea. In this case the overflow protection goes after the refactor.
Do you want them also output to
It may not be necessary to zero the memory (even with
The value of
"zero-mem" is a sub-option of the first.
Originally maybe, but now smart blend uses 9 such buffers: https://github.com/jellyfin/JavascriptSubtitlesOctopus/blob/f4625ac313b318bd5d2e0ae18679ff516370bae6/src/SubtitleOctopus.cpp#L98-L103 |
eac55b6
to
516c6d4
Compare
Currently, if #124 is fine, it should go first. |
Only for testing the compilation of this file. [part of] Rework buffer into C++ class Cherry-picked from: jellyfin@6d3a5c7
Cherry-picked from: jellyfin@6d3a5c7 Add 'ReusableBuffer::capacity' from [Restructure renderBlend so it can return multiple pieces; JS side not ready yet] Cherry-picked from: jellyfin@0cc2bf8 Move private data members to the top. Rename 'ReusableBuffer::take' -> 'ReusableBuffer::ensure_size'.
516c6d4
to
54c8384
Compare
The “Allow to compile CPP-file alone” commit has been merged.
Using some custom magic constant for the canvas dimensions is not the right way to prevent typewidth overflows. I have an untested branch started several weeks ago, which would replace both this and the overflow PR, but hadn't the time to finish + test it yet. Can you clarify what requirements are actually necessary for concretly planned or in jellyfin already existing features? |
But you can trim the canvas to a reasonable size.
|
Type overflows have nothing to do with libass or any notion of a "reasonable" canvas size (if you want to do the latter there’s an JSO option for this), but with the sizes of the underlying architecture and how those are mapped to C types. Any custom magic constant is incorrect in that it either is below the minimum size required by ISO and may needlessly limit, or it is above the minimum and may not actually prevent overflows.
You obviously still know what size you need beforehand, you just might need to do an overflow check before — or since
We could instead add an option to query a zero-initialised buffer from |
Those I ask because if you know the range of data you're working with, you don't have to get too defensive.
If you don't limit them, you will constantly get memory allocation errors.
Then the size will be calculated twice: outside the buffer and inside the buffer.
Little by little such immeasurable places can grow into measurable one. |
No. And the overflow happens in pure C.
32bit is well above the minimum required by ISO, and unless it’s actually requested it won't grow that big anyway. |
The alternative has now been tested and I didn't spot any issues. Let’s move further discussion to #133. |
Cherry-picked from: jellyfin@6d3a5c7
Cherry-picked from (part of): jellyfin@0cc2bf8
This is the only thing I can extract with such strict requirements in your repo. 😐
* and my own principles of porting the results of teamwork from the fork.