From 1ee36baa5399f45c6845ff96d15bc743d978d530 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Tue, 9 Dec 2025 19:04:17 -0500 Subject: [PATCH] fixes memory corruption --- lib/airplay_video.c | 60 +++++++++++++++++++++++++++++++++++++-------- lib/airplay_video.h | 3 +++ lib/http_handlers.h | 24 +++++++++--------- 3 files changed, 66 insertions(+), 21 deletions(-) diff --git a/lib/airplay_video.c b/lib/airplay_video.c index 921f0e4..0cd8d4c 100644 --- a/lib/airplay_video.c +++ b/lib/airplay_video.c @@ -39,22 +39,46 @@ struct airplay_video_s { char *apple_session_id; char *playback_uuid; char *uri_prefix; + char *local_uri_prefix; + char *playback_location; char *language_name; char *language_code; const char *lang; - char *local_uri_prefix; int next_uri; int FCUP_RequestID; float start_position_seconds; float resume_position_seconds; playback_info_t *playback_info; - // The local port of the airplay server on the AirPlay server - unsigned short airplay_port; char *master_playlist; media_item_t *media_data_store; int num_uri; }; +#if 0 //used for debugging a memory issue +void print_airplay_video(airplay_video_t *airplay_video, const char *title) { + printf("-------------------------start %s -----------------------------------------\n", title); + printf("%p airplay_video\n", airplay_video); + printf("%p airplay_video->raop %p\n", &(airplay_video->raop), airplay_video->raop); + printf("%p airplay_video->apple_session_id %p %s\n", &(airplay_video->apple_session_id), airplay_video->apple_session_id, airplay_video->apple_session_id ); + printf("%p airplay_video->playback_uuid %p %s\n", &(airplay_video->playback_uuid), airplay_video->playback_uuid, airplay_video->playback_uuid); + printf("%p airplay_video->uri_prefix %p %s\n", &(airplay_video->uri_prefix), airplay_video->uri_prefix, airplay_video->uri_prefix); + printf("%p airplay_video->playback_location %p %s\n", &(airplay_video->playback_location), airplay_video->playback_location, airplay_video->playback_location); + printf("%p airplay_video->local_uri_prefix %p %s\n", &(airplay_video->local_uri_prefix), airplay_video->local_uri_prefix, airplay_video->local_uri_prefix); + printf("%p airplay_video->language_name %p %s\n", &(airplay_video->language_name), airplay_video->language_name, airplay_video->language_name); + printf("%p airplay_video->language_code %p %s\n", &(airplay_video->language_code), airplay_video->language_code, airplay_video->language_code); + printf("%p airplay_video->lang %p %s\n", &(airplay_video->lang), airplay_video->lang, airplay_video->lang); + printf("%p airplay_video->next_uri %d\n", &(airplay_video->next_uri), airplay_video->next_uri); + printf("%p airplay_video->FCUP_request_id %d\n", &(airplay_video->FCUP_RequestID), airplay_video->FCUP_RequestID); + printf("%p airplay_video->start_position_seconds %f\n", &(airplay_video->start_position_seconds), airplay_video->start_position_seconds); + printf("%p airplay_video->resume_position_seconds %f\n", &(airplay_video->resume_position_seconds), airplay_video->resume_position_seconds); + printf("%p airplay_video->playback_info %p\n", &(airplay_video->playback_info), airplay_video->playback_info); + printf("%p airplay_video->master_playlist %p\n", &(airplay_video->master_playlist), airplay_video->master_playlist); + printf("%p airplay_video->media_data_store %p\n", &(airplay_video->media_data_store), airplay_video->media_data_store); + printf("%p airplay_video->num_uri %d\n", &(airplay_video->num_uri), airplay_video->num_uri); + printf("--------------------------end------------------------------------------\n"); +} +#endif + // initialize airplay_video service. airplay_video_t *airplay_video_init(raop_t *raop, unsigned short http_port, const char *lang) { char uri[] = "http://localhost:"; @@ -72,22 +96,20 @@ airplay_video_t *airplay_video_init(raop_t *raop, unsigned short http_port, cons airplay_video->lang = lang; /* create local_uri_prefix string */ snprintf(port, sizeof(port), "%u", http_port); - airplay_video->local_uri_prefix = (char *) calloc (strlen(uri) + strlen(port) + 1, sizeof(char)); - memcpy(airplay_video->local_uri_prefix, uri, strlen(uri)); - memcpy(airplay_video->local_uri_prefix + strlen(uri), port, strlen(port)); - //printf(" %p %p\n", airplay_video, get_airplay_video(raop)); + size_t len = strlen(uri) + strlen(port); + airplay_video->local_uri_prefix = (char *) calloc (len + 1, sizeof(char)); + strcat(airplay_video->local_uri_prefix, uri); + strcat(airplay_video->local_uri_prefix, port); airplay_video->raop = raop; airplay_video->FCUP_RequestID = 0; - airplay_video->apple_session_id = NULL; - airplay_video->start_position_seconds = 0.0f; airplay_video->playback_uuid = NULL; airplay_video->uri_prefix = NULL; + airplay_video->playback_location = NULL; airplay_video->language_code = NULL; airplay_video->language_name = NULL; - airplay_video->media_data_store = NULL; airplay_video->master_playlist = NULL; airplay_video->num_uri = 0; @@ -110,6 +132,9 @@ airplay_video_destroy(airplay_video_t *airplay_video) { if (airplay_video->local_uri_prefix) { free(airplay_video->local_uri_prefix); } + if (airplay_video->playback_location) { + free(airplay_video->playback_location); + } if (airplay_video->language_name) { free(airplay_video->language_name); } @@ -159,6 +184,17 @@ void set_uri_prefix(airplay_video_t *airplay_video, const char *uri_prefix, size str = NULL; } +void set_playback_location(airplay_video_t *airplay_video, const char *location, size_t len) { + assert(location && len ); + char *str = (char *) calloc(len + 1, sizeof(char)); + strncpy(str, location, len); + if (airplay_video->playback_location) { + free(airplay_video->playback_location); + } + airplay_video->playback_location = str; + str = NULL; +} + void set_language_name(airplay_video_t *airplay_video, const char *language_name, size_t len) { assert(language_name && len ); char *str = (char *) calloc(len + 1, sizeof(char)); @@ -216,6 +252,10 @@ const char *get_playback_uuid(airplay_video_t *airplay_video) { return (const char *) (!airplay_video ? NULL : airplay_video->playback_uuid); } +const char *get_playback_location(airplay_video_t *airplay_video) { + return (const char *) (!airplay_video ? NULL : airplay_video->playback_location); +} + const char *get_uri_prefix(airplay_video_t *airplay_video) { return (const char *) airplay_video->uri_prefix; } diff --git a/lib/airplay_video.h b/lib/airplay_video.h index 8a547a4..5a232ea 100644 --- a/lib/airplay_video.h +++ b/lib/airplay_video.h @@ -27,6 +27,7 @@ typedef struct airplay_video_s airplay_video_t; typedef struct media_item_s media_item_t; +void print_airplay_video(airplay_video_t *airplay_video, const char *title); void set_apple_session_id(airplay_video_t *airplay_video, const char *apple_session_id, size_t len); const char *get_apple_session_id(airplay_video_t *airplay_video); void set_start_position_seconds(airplay_video_t *airplay_video, float start_position_seconds); @@ -39,6 +40,8 @@ const char *get_playback_uuid(airplay_video_t *airplay_video); void set_uri_prefix(airplay_video_t *airplay_video, const char *uri_prefix, size_t len); const char *get_uri_prefix(airplay_video_t *airplay_video); char *get_uri_local_prefix(airplay_video_t *airplay_video); +void set_playback_location(airplay_video_t *airplay_video, const char *location, size_t len); +const char *get_playback_location(airplay_video_t *airplay_video); void set_language_code(airplay_video_t *airplay_video, const char *language_code, size_t len); const char *get_language_code(airplay_video_t *airplay_video); void set_language_name(airplay_video_t *airplay_video, const char *language_name, size_t len); diff --git a/lib/http_handlers.h b/lib/http_handlers.h index 14e4635..d6c5fb7 100644 --- a/lib/http_handlers.h +++ b/lib/http_handlers.h @@ -484,7 +484,6 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t goto post_action_error; } logger_log(conn->raop->logger, LOGGER_DEBUG, "action type is %s", type); - /* check that plist structure is as expected*/ plist_t req_params_node = NULL; if (PLIST_IS_DICT (req_root_node)) { @@ -493,7 +492,6 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t if (!PLIST_IS_DICT (req_params_node)) { goto post_action_error; } - if (!strcmp(type,"playlistRemove")) { plist_t req_params_item_node = plist_dict_get_item(req_params_node, "item"); if (!req_params_item_node || !PLIST_IS_DICT (req_params_item_node)) { @@ -653,9 +651,8 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t get_next_FCUP_RequestID(airplay_video)); set_next_media_uri_id(airplay_video, ++uri_num); } else { - char * uri_local_prefix = get_uri_local_prefix(airplay_video); conn->raop->callbacks.on_video_play(conn->raop->callbacks.cls, - strcat(uri_local_prefix, "/master.m3u8"), + get_playback_location(airplay_video), get_start_position_seconds(airplay_video)); } @@ -744,9 +741,8 @@ http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *r airplay_video = conn->raop->airplay_video[id]; assert(airplay_video); set_apple_session_id(airplay_video, apple_session_id, strlen(apple_session_id)); - char * uri_local_prefix = get_uri_local_prefix(airplay_video); conn->raop->callbacks.on_video_play(conn->raop->callbacks.cls, - strcat(uri_local_prefix, "/master.m3u8"), + get_playback_location(airplay_video), get_start_position_seconds(airplay_video)); plist_mem_free(playback_uuid); plist_free(req_root_node); @@ -792,7 +788,7 @@ http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *r conn->raop->current_video = id; conn->raop->airplay_video[id] = airplay_video; count++; - //printf("created new airplay_video %p %s\n\n", airplay_video, get_playback_uuid(airplay_video)); + printf("created new airplay_video %p %s\n\n", airplay_video, get_playback_uuid(airplay_video)); } else { logger_log(conn->raop->logger, LOGGER_ERR, "failed to allocate airplay_video[%d]\n", id); exit(-1); @@ -847,19 +843,25 @@ http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *r } set_start_position_seconds(airplay_video, (float) start_position_seconds); - if (!strstr(playback_location, "/master.m3u8")) { + const char *uri_suffix = strstr(playback_location, "/master.m3u8"); + if (!uri_suffix) { logger_log(conn->raop->logger, LOGGER_ERR, "Content-Location has unsupported form:\n%s\n", playback_location); goto play_error; } else { + size_t len = strlen(get_uri_local_prefix(airplay_video)) + strlen(uri_suffix); + char *location = (char *) calloc(len + 1, sizeof(char)); + strcat(location, get_uri_local_prefix(airplay_video)); + strcat(location, uri_suffix); + set_playback_location(airplay_video, location, strlen(location)); + free(location); char *uri_prefix = (char *) calloc(strlen(playback_location) + 1, sizeof(char)); strncpy(uri_prefix, playback_location, strlen(playback_location)); - char *ptr = strstr(uri_prefix, "/master.m3u8"); - *ptr = '\0'; + char *end = strstr(uri_prefix, "/master.m3u8"); + *end = '\0'; set_uri_prefix(airplay_video, uri_prefix, strlen(uri_prefix)); free (uri_prefix); } set_next_media_uri_id(airplay_video, 0); - printf("FCUP REQUEST\n"); fcup_request((void *) conn, playback_location, apple_session_id, get_next_FCUP_RequestID(airplay_video)); plist_mem_free(playback_location);