Add a new overflow-safe function to check if region p2 of size s2 fits
completely in p1 of size s1 and, if it does, return the amount of bytes
in p1 that come after the end of p2. Use this to bounds check the pod
iterators while ensuring that the pointer is bounds checked before being
dereferenced.
The spa_pod*_next() functions can still create an out-of-bounds pointer,
but this will not be dereferenced. Fixing this requires either
additional complexity in these functions or forbidding POD structs,
objects, and sequences that have a length that is not a multiple of 8
bytes.
Fixes: 92ac9a355f ("spa: add spa_ptrinside")
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
Add a new overflow safe function to check if region p2 of size s2 fits
completely in p1 of size s1. Use this to bounds check the pod iterators.
Fixes#3727
Make sure that NULL params don't cause -EINVAL but ignore them.
Don't add empty param objects. this makes it possible to clear all previous
params by setting an empty object.
added cleanup of unused variables and fix warning about missing initializers
to resolve build warnings in pipewire-rs
Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Fixes the return type of spa_pod_builder_control() from uint32_t to int.
Since the function returns the int returned by spa_pod_builder_raw,
the return type of the function should also be an int.
This fixes several integer overflow problems in the POD parser, as well
as fixing a returns-twice warning from GCC and integer truncation
problems in SPA_FLAG_CLEAR and SPA_ROUND_DOWN_N. The integer overflows
can result in a tiny POD being treated as a huge one, causing
out-of-bounds reads.
spa_pod_parser_can_collect and spa_pod_parser_getv were inconsistent
with each other. When parsing crafted POD, this could cause a type
confusion or stack overflow.
When we are already past the size of the buffer, don't bother calling
the overflow callback anymore, the buffer is already corrupted.
Otherwise it would be possible to have the overflow callback fail the
first time around, some data will be skipped, and then the next
overflow callback would succeed, giving the impression that all is
fine.
Add a unit test for this.
Resizes the buffer dynamically. Be careful with getting the address
of a pod in the buffer, it might not be valid after building more stuff
with the builder.
If the supplied buffer has smaller (or equal) size than the
length of the string, then `strncpy()` will not place a null
terminator in the buffer.
Fix that by always setting the last byte of the buffer to zero.
The Doxygen "Modules" page is not very illuminative, as different parts
of the API are mixed together and not all parts are included.
Try to address this:
Put all parts of the public API to some Doxygen group, usually one group
per header file. Use short, systematic names.
Make these groups sub-groups of a few top-level groups, roughly
corresponding to the different logical parts of the API (core, impl,
stream, filter, spa, utilities).
Add a DONT_FIXATE flag to spa_pod_props. The flag avoids fixation
of the property by spa_pod_fixate().
When filtering properties, 'and' the flags together in the filtered
property. This mostly preserves the merged property flags. It also
merges the DONT_FIXATE flags so that when both sides can handle
the non-fixated result, it will be returned.
This can be used to let PipeWire filter out the common property
fields and leave the final selection of fields to the producer. This can
only work when the final selected field can be transported in some
other way than the format param, like on the buffer fields or in
metadata. One use case is negotiation of the DMABUF modifiers.
See #1084
Subdirectories buffer, control, debug, monitor, pod, support and utils, others
are still missing. Headers are grouped either per subdirectory (e.g. buffer/
gets added to group spa_buffer) or per-file (e.g. spa_json is a separate
group), whatever seemed like the most sensible approach.
This flag is used to announce that the respective key is mandatory and
therefore the object containing this key is not suitable to be merged
with other objects missing it.
SPA_MEMBER is misleading, all we're doing here is pointer+offset and a
type-casting the result. Rename to SPA_PTROFF which is more expressive (and
has the same number of characters so we don't need to re-indent).
This is needed for example for Clang compiler which uses different
annotations than GCC. It will make WebRTC to happily use PipeWire
since the spa library is header-only and WebRTC defaults to use
Clang with -Wimplicit-fallthrough.
Add a READONLY property flag to makr properties READONLY
Set the base_volume and volume_step in the acp device
Send the base volume and step as REAONLY properties. Use these
in pulse layer.
Add HARDWARE flag to mark a property that does some hardware control.
Mark the device volume/mute property as HARDWARE or not.
Use the HARDWARE property in pulse to set the right flags.
Always take the state of the builder to get the newly filtered
object, even in the case there is no filter.
Handle the case where we can't copy the pod in the case of
a NULL filter by reverting the state of the builder.
Rework the function a bit to make it possible to pass a NULL
result (to calculate the required size, for example)
Fixes#226
The choice array might have excess elements when the type has been
changed, for example by fixation. This is not a problem and the
excess elements should simply be ignored.
If an ID cannot be de-referenced, e.g., because the builder buffer is
too small, spa_pod_filter() still reports success, but the result is
NULL. Any subsequent access to result will cause a segfault.
Return an error if no pod is found to properly propagate and handle the
error.
The segfault can be reproduced by using the v4l2 module with Vivid
devices [0], because the buffer for the v4l2 controls is too small.
[0] https://github.com/PipeWire/pipewire/issues/138