Merge topic branch t/overflow into master This series implements a new memory allocation API which checks for overflows. The first part of the series just renames the main allocation functions. Later patches in the series implement allocators which take two size_t arguments (like calloc(3)) and check whether the multiplication overflows by employing the __builtin_mul_overflow() primitive supported by gcc and clang. This requires us to bump the lowest supported gcc and clang version. * refs/heads/t/overflow: build: Compile with -ftrapv. string: Introduce arr_zalloc(). string: Introduce arr_alloc(). string: Introduce arr_realloc() and check for integer overflow. string: Rename para_calloc() -> zalloc(). string: Rename para_malloc() -> alloc(). string: Overhaul para_strdup().
string: Introduce arr_alloc(). Change all callers of alloc() which pass a product of two integers as the allocation size to call the new function instead. This function aborts if the multiplication overflows. With arr_alloc() in place, alloc() reduces to a trivial wrapper which calls new arr_alloc() with the first argument equal to one.
string: Rename para_malloc() -> alloc(). Just because it's shorter and matches the naming of the new allocators we are about to introduce. The bulk of this patch was created with sed -i 's/para_malloc/alloc/g' *.c *.h yy/mp.y
mp4: Don't abort on truncated files. If the source file got truncated it may happen that a chunk cannot be read because the computed file offset is beyond EOF. Currently, aac_afh_get_chunk() aborts in this case because we assert that the file offset is within range. Return a proper error code instead and also change aac_get_file_info() to bail out if aac_afh_get_chunk() returns negative.
mp4: Rename mp4_open_read() to mp4_open(). The function may be called with the intention to update the meta tags later by calling mp4_update_meta(), albeit mp4_open_meta() is cheaper if the caller only wants to modify the metadata. The old name is thus slightly misleading, and it's longer.
mp4: Rename mp4_meta_update() to mp4_update_meta(). Just to be consistent with mp4_open_meta() and friends.
mp4: Fail early on invalid sample rate or sample count. If the sample rate or the sample count happen to be zero, we should fail the open rather than return success and let the caller deal with it. This patch moves the corresponding sanity checks from aac_afh.c to mp4_open_read() of mp4.c. The sample rate is always read while sample count is skipped for metadata-only opens. So the first check belongs to the common open_file() while the second check needs to go to mp4_open_read().
mp4: Remove E_MP4_BAD_CHANNEL_COUNT. If the mp4 file does not contain an m4a atom, the channel count stays at zero and open_file() returns -E_MP4_TRACK in this case. So the check in aac_afh.c for a non-positive return value from mp4_get_channel_count() can never trigger. Replace the check by an assertion and remove the error code. Also, let mp4_get_channel_count() return uint16_t as the number of channels is stored as an unsigned 16 bit number in the mp4 file.
mp4: Improve mp4_get_sample_size(). Use an unsigned type for the sample number and check that the passed number is within range. Since the function can fail now, let it return int and return the sample size via an additional pointer argument.
mp4: Check the return value of ->truncate(). This callback is implemented as a simple wrapper for the ftruncate() system call, which can fail for a number of reasons. Currently the callback returns unsigned and the return value is ignored. Fortunately, this is easy to fix.
mp4: Replace the five tag value functions by a single one. It's easier to let the caller pass the tag item string than to have one caller for each of the five tags of interest. This commit renames meta_find_by_name() to mp4_get_tag_value(), makes it public and removes its five callers from mp4.c. The only user is _aac_afh_get_taginfo() of aac_afh.c, which needs to be adjusted accordingly. Kill the pointless underscore while at it.
mp4: Provide whence parameter for the seek callback. This adds a parameter to make ->seek() work like the lseek(2) system call. This is easy to implement in both the memory-mapped callback case used to retrieve the file information and the metadata update case where ->seek() is a trivial wrapper for lseek(2). With the additional functionality in place we don't need to track the file size and the current file offset any more in mp4.c as these values can now be obtained by calling ->seek() with a zero offset and whence set to SEEK_END and SEEK_CUR, respectively. This also makes the code more robust against corrupt mp4 files because we no longer rely on the values from the atom headers to compute the file size. The way mp4.c calls ->seek() should never cause the underlying lseek(2) system call to fail. Therefore it suffices to check the return value only in the callback wrapper and abort on failure.
mp4: Implement error checking for the write path. Although the ->write callback has a return value, it is of unsigned type and is never checked. Fix this by changing the prototype to match that of the write(2) system call, check the return value of the callback in the write_data() wrapper of mp4.c and propagate paraslash error codes back to aac_afh.c via the public mp4_meta_update(). While at it, handle short writes and EINTR properly, and fix the indentation of the callback structure in mp4.h.
mp4: Eliminate duplication between the two open functions. The only difference between mp4_open_read() and mp4_open_meta() is that they pass different values for the meta_only flag to parse_root_atoms(). We can avoid some duplication by moving the common code to parse_root_atoms(). Rename that function to open_file() because it now does more than just parsing atoms. The patch also changes the prototype of both public open functions to return an integer error code in addition to the pointer to an mp4 structure. This allows us to gradually improve the error diagnostics.
mp4: Hide tracks array. All functions of mp4.c operate on the first audio track. This patch makes this fact implicit which allows us to remove the public mp4_get_total_tracks() and mp4_is_audio_track(). Moreover, the track parameter can be removed from all public functions. If no audio track was found in the mp4 file, we now return an error from two public open functions of mp4.c. Otherwise, we maintain a pointer to the first audio track within the mp4 structure and use that to identify the track rather than letting the API users pass the track number.
mp4: Provide return value for mp4_set_sample_position(). This function fails if the given parameters are invalid. Detect this and return EINVAL in this case. Add corresponding error checking to the aac audio format handler.
mp4: Rename mp4_total_tracks() to mp4_get_total_tracks(). Just to be consistent with other public functions whose name contain a predicate. Move the function down to related functions.
mp4: Improve handling of read errors. Currently read_data() of mp4.c is an atrocious mess. The ->read() callback is defined to return uint32_t, but the return value is stored in a signed 32 bit integer. Moreover, read_data() contains a dead store, it handles neither short nor interrupted reads correctly, and it moves the file position backwards on errors. While this is easy to fix, a more intricate problem is that most callers of read_data(), including all read_intX() helpers, ignore the return value of read_data() and return uninitialized stack contents in the error case. This is kind of dealt with by the ->read_error member of struct mp4, but this not more than a kludge, which, according to the comments, was applied after several CVEs had been filed against the library. Let's DTRT here, even though it adds a fair amount of new code: Check the return value of each read operation and fail early on errors. We have to distinguish three cases: error, EOF, and success, encoded as return values -1, 0 and 1, respectively. This commit converts most functions which read from an mp4 file to this convention. More work is required as return values are not checked everywhere yet. This was left for subsequent commits to keep the already large patch within reasonable size. Since we don't rely on ->read_error of struct mp4 any more, it can be removed.
aac_afh: Simplify aac_afh_rewrite_tags(). This function was disgusting because it listed the five standard tags in three different ways. The new replace_or_add_tag() avoids this issue.
mp4: Drop metadata parameter from mp4_meta_update(). The function can as well access the modified metadata structure via the mp4 pointer. Drop the parameter also from modify_moov() for the same reason.