diff --git a/deps/libakstdlib b/deps/libakstdlib index 95e5002..f8425b8 160000 --- a/deps/libakstdlib +++ b/deps/libakstdlib @@ -1 +1 @@ -Subproject commit 95e500251260e2ce5984226aa12079969bffd873 +Subproject commit f8425b872909fa2680842cc5d55c355c63bfa7ff diff --git a/src/game.c b/src/game.c index 71733c3..331e155 100644 --- a/src/game.c +++ b/src/game.c @@ -43,6 +43,20 @@ MIX_Mixer *akgl_mixer = NULL; MIX_Track *akgl_tracks[AKGL_GAME_AUDIO_MAX_TRACKS]; akgl_Game game; +static akerr_ErrorContext *write_exact(const void *ptr, size_t size, size_t nmemb, FILE *fp) +{ + size_t transferred; + + return aksl_fwrite(ptr, size, nmemb, fp, &transferred); +} + +static akerr_ErrorContext *read_exact(void *ptr, size_t size, size_t nmemb, FILE *fp) +{ + size_t transferred; + + return aksl_fread(ptr, size, nmemb, fp, &transferred); +} + void akgl_game_lowfps(void) { SDL_Log("Low FPS! %d", game.fps); @@ -188,9 +202,9 @@ void akgl_game_save_actorname_iterator(void *userdata, SDL_PropertiesID props, c PREPARE_ERROR(e); ATTEMPT { FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer"); - CATCH(e, aksl_fwrite((char *)name, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp)); + CATCH(e, write_exact((char *)name, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp)); actor = SDL_GetPointerProperty(props, name, NULL); - CATCH(e, aksl_fwrite(&actor, 1, sizeof(akgl_Actor *), fp)); + CATCH(e, write_exact(&actor, 1, sizeof(akgl_Actor *), fp)); } CLEANUP { } PROCESS(e) { } FINISH_NORETURN(e); @@ -210,8 +224,8 @@ void akgl_game_save_spritename_iterator(void *userdata, SDL_PropertiesID props, ATTEMPT { FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer"); sprite = SDL_GetPointerProperty(props, name, NULL); - CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp)); - CATCH(e, aksl_fwrite(&sprite, 1, sizeof(akgl_Sprite *), fp)); + CATCH(e, write_exact((char *)name, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp)); + CATCH(e, write_exact(&sprite, 1, sizeof(akgl_Sprite *), fp)); } CLEANUP { } PROCESS(e) { } FINISH_NORETURN(e); @@ -231,8 +245,8 @@ void akgl_game_save_spritesheetname_iterator(void *userdata, SDL_PropertiesID pr ATTEMPT { FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer"); spritesheet = SDL_GetPointerProperty(props, name, NULL); - CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp)); - CATCH(e, aksl_fwrite(&spritesheet, 1, sizeof(akgl_SpriteSheet *), fp)); + CATCH(e, write_exact((char *)name, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp)); + CATCH(e, write_exact(&spritesheet, 1, sizeof(akgl_SpriteSheet *), fp)); } CLEANUP { } PROCESS(e) { } FINISH_NORETURN(e); @@ -252,8 +266,8 @@ void akgl_game_save_charactername_iterator(void *userdata, SDL_PropertiesID prop ATTEMPT { FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer"); character = SDL_GetPointerProperty(props, name, NULL); - CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp)); - CATCH(e, aksl_fwrite(&character, 1, sizeof(akgl_Character *), fp)); + CATCH(e, write_exact((char *)name, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp)); + CATCH(e, write_exact(&character, 1, sizeof(akgl_Character *), fp)); } CLEANUP { } PROCESS(e) { } FINISH_NORETURN(e); @@ -286,29 +300,29 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save_actors(FILE *fp) AKGL_REGISTRY_ACTOR, &akgl_game_save_actorname_iterator, (void *)fp); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp)); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_Actor *), fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_Actor *), fp)); // write the sprite name pointer table SDL_EnumerateProperties( AKGL_REGISTRY_SPRITE, &akgl_game_save_spritename_iterator, (void *)fp); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp)); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_Sprite *), fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_Sprite *), fp)); // write the spritesheet name pointer table SDL_EnumerateProperties( AKGL_REGISTRY_SPRITESHEET, &akgl_game_save_spritesheetname_iterator, (void *)fp); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp)); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_SpriteSheet *), fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_SpriteSheet *), fp)); // write the character name pointer table SDL_EnumerateProperties( AKGL_REGISTRY_CHARACTER, &akgl_game_save_charactername_iterator, (void *)fp); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp)); - CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_Character *), fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp)); + CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_Character *), fp)); } CLEANUP { } PROCESS(e) { } FINISH(e, true); @@ -323,7 +337,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save(char *fpath) ATTEMPT { FAIL_ZERO_BREAK(e, fpath, AKERR_NULLPOINTER, "NULL file path"); CATCH(e, aksl_fopen(fpath, "wb", &fp)); - CATCH(e, aksl_fwrite(&game, 1, sizeof(akgl_Game), fp)); + CATCH(e, write_exact(&game, 1, sizeof(akgl_Game), fp)); CATCH(e, akgl_game_save_actors(fp)); } CLEANUP { // CLEANUP must precede PROCESS: with the two transposed, the fclose @@ -363,8 +377,8 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_objectnamemap(FILE *fp, SDL_Pr // corrupt name table as a successful load. while ( done == false ) { ATTEMPT { - CATCH(e, aksl_fread((void *)&objname, 1, namelength, fp)); - CATCH(e, aksl_fread((void *)&ptr, 1, ptrlength, fp)); + CATCH(e, read_exact((void *)&objname, 1, namelength, fp)); + CATCH(e, read_exact((void *)&ptr, 1, ptrlength, fp)); // End of the map if ( ptr == 0x00 && objname[0] == 0x00 ) { done = true; @@ -456,7 +470,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath) ATTEMPT { CATCH(e, aksl_fopen(fpath, "rb", &fp)); - CATCH(e, aksl_fread((void *)&savegame, 1, sizeof(akgl_Game), fp)); + CATCH(e, read_exact((void *)&savegame, 1, sizeof(akgl_Game), fp)); CATCH(e, akgl_game_load_versioncmp("library", (char *)&savegame.libversion, (char *)AKGL_VERSION)); CATCH(e, akgl_game_load_versioncmp("game", (char *)&savegame.version, (char *)&game.version)); FAIL_NONZERO_RETURN( diff --git a/src/tilemap.c b/src/tilemap.c index 380dd1c..888450a 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -596,7 +596,7 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest) //CATCH(errctx, akgl_heap_next_string(&tmpstr)); //CATCH(errctx, akgl_string_initialize(tmpstr, NULL)); //SDL_snprintf(tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), fname); - CATCH(errctx, aksl_realpath(fname, (char *)&dirnamestr->data)); + CATCH(errctx, aksl_realpath(fname, (char *)&dirnamestr->data, sizeof(dirnamestr->data))); dirname((char *)&dirnamestr->data); json = json_load_file(fname, 0, &error); diff --git a/src/util.c b/src/util.c index 5b8f3aa..181b57d 100644 --- a/src/util.c +++ b/src/util.c @@ -54,9 +54,16 @@ akerr_ErrorContext *akgl_path_relative_root(char *root, char *path, akgl_String FAIL_RETURN(e, AKERR_OUTOFBOUNDS, "Total path length (%d) is greater than maximum akgl_String length (%d)", (rootlen + pathlen), AKGL_MAX_STRING_LENGTH); } DISABLE_GCC_WARNING_FORMAT_TRUNCATION - CATCH(e, aksl_sprintf(&count, (char *)&pathbuf->data, "%s/%s", root, path)); + CATCH(e, aksl_snprintf( + &count, + (char *)&pathbuf->data, + sizeof(pathbuf->data), + "%s/%s", + root, + path + )); RESTORE_GCC_WARNINGS - CATCH(e, aksl_realpath((char *)&pathbuf->data, (char *)&strbuf->data)); + CATCH(e, aksl_realpath((char *)&pathbuf->data, (char *)&strbuf->data, sizeof(strbuf->data))); CATCH(e, akgl_string_copy(strbuf, dst, 0)); } CLEANUP { IGNORE(akgl_heap_release_string(strbuf)); @@ -80,7 +87,7 @@ akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dst) ATTEMPT { // Is path relative to our current working directory? - CATCH(e, aksl_realpath(path, (char *)&strbuf->data)); + CATCH(e, aksl_realpath(path, (char *)&strbuf->data, sizeof(strbuf->data))); // Yes it is. strbuf->data contains the absolute path. CATCH(e, akgl_string_copy(strbuf, dst, 0)); } CLEANUP { @@ -109,7 +116,7 @@ akerr_ErrorContext *akgl_path_relative_from(char *path, char *from, akgl_String FAIL_ZERO_RETURN(e, path, AKERR_NULLPOINTER, "path"); FAIL_ZERO_RETURN(e, from, AKERR_NULLPOINTER, "from"); PASS(e, akgl_heap_next_string(&dirnamestr)); - PASS(e, aksl_realpath(from, (char *)&dirnamestr->data)); + PASS(e, aksl_realpath(from, (char *)&dirnamestr->data, sizeof(dirnamestr->data))); dirname((char *)&dirnamestr->data); SUCCEED_RETURN(e);