Skip to content

Commit

Permalink
Add XM_DEFENSIVE and XM_DEMO_MODE options.
Browse files Browse the repository at this point in the history
  • Loading branch information
Artefact2 committed Feb 22, 2015
1 parent 343ca92 commit ac0bbdb
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 12 deletions.
19 changes: 15 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,33 @@ ADD_DEFINITIONS(-D${name}=0)
ENDIF()
ENDFUNCTION()

OPTION_AND_DEFINE(XM_DEBUG "Enable debugging messages" "ON")
OPTION_AND_DEFINE(XM_BIG_ENDIAN "Assume big endian byte order (default: little endian assumed)" "OFF")
OPTION_AND_DEFINE(XM_DEBUG "Enable debug symbols and print debugging messages to stderr" "ON")
OPTION_AND_DEFINE(XM_DEFENSIVE "Defensively check XM data for errors/inconsistencies" "ON")
OPTION_AND_DEFINE(XM_BIG_ENDIAN "Use big endian byte order (unfinished)" "OFF")
OPTION_AND_DEFINE(XM_LINEAR_INTERPOLATION "Use linear interpolation (CPU hungry)" "ON")
OPTION_AND_DEFINE(XM_RAMPING "Enable ramping (smooth volume/panning transitions, CPU hungry)" "ON")

OPTION(XM_BUILD_SHARED_LIBS "Build shared library" "ON")
OPTION(XM_BUILD_EXAMPLES "Build example programs" "ON")
OPTION(XM_DEMO_MODE "Optimize for size (then link statically against libxms and strip dead code)" "OFF")

ADD_DEFINITIONS("-g -Os -Wall -pedantic --std=c11")
ADD_DEFINITIONS("-Wall -pedantic --std=c11")

IF(XM_DEBUG)
ADD_DEFINITIONS("-g")
ENDIF()

IF(XM_DEMO_MODE)
ADD_DEFINITIONS("-Os")
ADD_DEFINITIONS("-fdata-sections -ffunction-sections")
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -dead_strip")
ELSE()
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
ENDIF()
ELSE()
ADD_DEFINITIONS("-O2")
ENDIF()

LIST(APPEND XM_INCLUDE_DIRS "${libxm_SOURCE_DIR}/include")
LIST(APPEND XM_LIBRARIES "m")
Expand All @@ -34,4 +46,3 @@ ADD_SUBDIRECTORY(src)
IF(XM_BUILD_EXAMPLES)
ADD_SUBDIRECTORY(examples)
ENDIF()

7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
build-debug: build
@cd build && cmake -D XM_DEBUG=ON -D XM_DEFENSIVE=ON ..

build-demo: build
@cd build && cmake -D XM_DEBUG=OFF -D XM_DEFENSIVE=OFF -D XM_DEMO_MODE=ON ..

build:
@mkdir -p build
@cd build && cmake ..

dist-clean:
@rm -Rf build
Expand Down
14 changes: 12 additions & 2 deletions src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ int xm_create_context_safe(xm_context_t** ctxp, const char* moddata, size_t modd
char* mempool;
xm_context_t* ctx;

if((ret = xm_check_header_sanity(moddata, moddata_length))) {
DEBUG("xm_check_header_sanity() returned %i", ret);
#if XM_DEFENSIVE
if((ret = xm_check_sanity_preload(moddata, moddata_length))) {
DEBUG("xm_check_sanity_preload() returned %i, module is not safe to load", ret);
return 1;
}
#endif

bytes_needed = xm_get_memory_needed_for_context(moddata, moddata_length);
mempool = malloc(bytes_needed);
Expand Down Expand Up @@ -67,6 +69,14 @@ int xm_create_context_safe(xm_context_t** ctxp, const char* moddata, size_t modd
ctx->row_loop_count = (uint8_t*)mempool;
mempool += MAX_NUM_ROWS * sizeof(uint8_t);

#if XM_DEFENSIVE
if((ret = xm_check_sanity_postload(ctx))) {
DEBUG("xm_check_sanity_postload() returned %i, module is not safe to play", ret);
xm_free_context(ctx);
return 1;
}
#endif

return 0;
}

Expand Down
26 changes: 23 additions & 3 deletions src/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ static inline void memcpy_pad(void* dst, size_t dst_len, const void* src, size_t
memset(dst_c + copy_bytes, 0, dst_len - copy_bytes);
}

int xm_check_header_sanity(const char* module, size_t module_length) {
#if XM_DEFENSIVE

int xm_check_sanity_preload(const char* module, size_t module_length) {
if(module_length < 60) {
return 4;
}
Expand All @@ -54,6 +56,24 @@ int xm_check_header_sanity(const char* module, size_t module_length) {
return 0;
}

int xm_check_sanity_postload(xm_context_t* ctx) {
/* @todo: plenty of stuff to do here… */

/* Check the POT */
for(uint8_t i = 0; i < ctx->module.length; ++i) {
if(ctx->module.pattern_table[i] >= ctx->module.num_patterns) {
DEBUG("module has invalid POT, pos %i references nonexistent pattern %i",
i,
ctx->module.pattern_table[i]);
return 1;
}
}

return 0;
}

#endif

size_t xm_get_memory_needed_for_context(const char* moddata, size_t moddata_length) {
size_t memory_needed = 0;
size_t offset = 60; /* Skip the first header */
Expand Down Expand Up @@ -153,7 +173,7 @@ char* xm_load_module(xm_context_t* ctx, const char* moddata, size_t moddata_leng
mod->patterns = (xm_pattern_t*)mempool;
mempool += mod->num_patterns * sizeof(xm_pattern_t);

mod->instruments = (xm_instrument_t*)mempool;
mod->instruments = (xm_instrument_t*)mempool;
mempool += mod->num_instruments * sizeof(xm_instrument_t);

uint16_t flags = READ_U32(offset + 14);
Expand All @@ -164,7 +184,7 @@ char* xm_load_module(xm_context_t* ctx, const char* moddata, size_t moddata_leng

READ_MEMCPY(mod->pattern_table, offset + 20, PATTERN_ORDER_TABLE_LENGTH);
offset += header_size;

/* Read patterns */
for(uint16_t i = 0; i < mod->num_patterns; ++i) {
uint16_t packed_patterndata_size = READ_U16(offset + 7);
Expand Down
14 changes: 12 additions & 2 deletions src/xm_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,21 @@ struct xm_sample_s {

/* ----- Internal API ----- */

/** Check the module header (first 60 bytes).
#ifdef XM_DEFENSIVE

/** Check the module data for errors/inconsistencies.
*
* @returns 0 if everything looks OK. Module should be safe to load.
*/
int xm_check_sanity_preload(const char*, size_t);

/** Check a loaded module for errors/inconsistencies.
*
* @returns 0 if everything looks OK.
*/
int xm_check_header_sanity(const char*, size_t);
int xm_check_sanity_postload(xm_context_t*);

#endif

/** Get the number of bytes needed to store the module data in a
* dynamically allocated blank context.
Expand Down

0 comments on commit ac0bbdb

Please sign in to comment.