Merge pull request #2395 from ArchitDewan/fix/atrac9-gradient-bounds
fix(ajm): reject ATRAC9 gradients beyond decoder bounds
This commit is contained in:
commit
40d50b3f16
|
|
@ -1,6 +1,9 @@
|
|||
enable_language(C)
|
||||
|
||||
set(LIBATRAC9_DIR ${CMAKE_SOURCE_DIR}/3rdparty/LibAtrac9/C/src)
|
||||
set(LIBATRAC9_PATCHED_DIR ${CMAKE_CURRENT_BINARY_DIR}/atrac9)
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${LIBATRAC9_DIR}/unpack.c)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/PatchLibAtrac9.cmake)
|
||||
add_library(atrac9 STATIC EXCLUDE_FROM_ALL
|
||||
${LIBATRAC9_DIR}/band_extension.c
|
||||
${LIBATRAC9_DIR}/bit_allocation.c
|
||||
|
|
@ -13,9 +16,10 @@ add_library(atrac9 STATIC EXCLUDE_FROM_ALL
|
|||
${LIBATRAC9_DIR}/quantization.c
|
||||
${LIBATRAC9_DIR}/scale_factors.c
|
||||
${LIBATRAC9_DIR}/tables.c
|
||||
${LIBATRAC9_DIR}/unpack.c
|
||||
${LIBATRAC9_PATCHED_DIR}/unpack.c
|
||||
${LIBATRAC9_DIR}/utility.c
|
||||
)
|
||||
target_include_directories(atrac9 PRIVATE ${LIBATRAC9_DIR})
|
||||
set_target_properties(atrac9 PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_library(libSceAjm.native SHARED EXCLUDE_FROM_ALL
|
||||
|
|
@ -31,6 +35,16 @@ target_link_libraries(libSceAjm.native PRIVATE atrac9 ffmpeg libc libkernel)
|
|||
configure_windows_unwind(libSceAjm.native)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(atrac9_gradient_tests tests/Atrac9Gradient.c ${LIBATRAC9_DIR}/bit_reader.c)
|
||||
target_include_directories(atrac9_gradient_tests PRIVATE ${LIBATRAC9_PATCHED_DIR} ${LIBATRAC9_DIR})
|
||||
target_compile_options(atrac9_gradient_tests PRIVATE -ffunction-sections -fdata-sections)
|
||||
if(APPLE)
|
||||
target_link_options(atrac9_gradient_tests PRIVATE LINKER:-dead_strip)
|
||||
else()
|
||||
target_link_options(atrac9_gradient_tests PRIVATE LINKER:--gc-sections)
|
||||
endif()
|
||||
add_test(NAME atrac9_gradient COMMAND atrac9_gradient_tests)
|
||||
|
||||
add_test_executable(guest_ajm_tests ${LIBS_INCLUDE_DIR}/tests/GuestAjm.cpp)
|
||||
target_include_directories(guest_ajm_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_ajm_tests PRIVATE libSceAjm.native libc)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
file(READ ${LIBATRAC9_DIR}/unpack.c libatrac9Unpack)
|
||||
set(libatrac9OldGuard "block->GradientEndUnit < 0 || block->GradientEndUnit >= 48")
|
||||
set(libatrac9NewGuard "block->GradientEndUnit < 0 || block->GradientEndUnit > 31")
|
||||
string(FIND "${libatrac9Unpack}" "${libatrac9OldGuard}" libatrac9GuardPosition)
|
||||
if(libatrac9GuardPosition EQUAL -1)
|
||||
message(FATAL_ERROR "LibAtrac9 gradient guard has changed; review the local bounds fix")
|
||||
endif()
|
||||
string(REPLACE "${libatrac9OldGuard}" "${libatrac9NewGuard}" libatrac9Unpack "${libatrac9Unpack}")
|
||||
file(MAKE_DIRECTORY ${LIBATRAC9_PATCHED_DIR})
|
||||
file(WRITE ${LIBATRAC9_PATCHED_DIR}/unpack.c "${libatrac9Unpack}")
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#include "unpack.c"
|
||||
#include <stdlib.h>
|
||||
|
||||
static void WriteBits(unsigned char* data, int* position, int value, int width)
|
||||
{
|
||||
for (int bit = width - 1; bit >= 0; --bit)
|
||||
{
|
||||
int offset = (*position)++;
|
||||
data[offset / 8] |= (unsigned char)(((value >> bit) & 1) << (7 - offset % 8));
|
||||
}
|
||||
}
|
||||
|
||||
static At9Status GradientStatus(int endUnit)
|
||||
{
|
||||
unsigned char data[4] = {0};
|
||||
int position = 0;
|
||||
WriteBits(data, &position, 0, 2);
|
||||
WriteBits(data, &position, 0, 6);
|
||||
WriteBits(data, &position, endUnit - 1, 6);
|
||||
WriteBits(data, &position, 0, 5);
|
||||
WriteBits(data, &position, 0, 5);
|
||||
WriteBits(data, &position, 0, 4);
|
||||
|
||||
Block block = {0};
|
||||
BitReaderCxt reader;
|
||||
InitBitReaderCxt(&reader, data, sizeof(data));
|
||||
return ReadGradientParams(&block, &reader);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (GradientStatus(31) != ERR_SUCCESS) return EXIT_FAILURE;
|
||||
if (GradientStatus(32) != ERR_UNPACK_GRAD_END_UNIT_OOB) return EXIT_FAILURE;
|
||||
if (GradientStatus(47) != ERR_UNPACK_GRAD_END_UNIT_OOB) return EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
Reference in New Issue