diff options
author | Eric Laurent <elaurent@google.com> | 2013-12-18 09:58:04 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2014-03-06 09:11:10 -0800 |
commit | 30bf0cc133ecab46b7999ac791ebe95d0c51d746 (patch) | |
tree | c441798b537a4947b179628bcd0a9340e43cbacd | |
parent | 52a64a571f037c5b519b98c69a3b47466d4accce (diff) | |
download | android_system_media-30bf0cc133ecab46b7999ac791ebe95d0c51d746.tar.gz android_system_media-30bf0cc133ecab46b7999ac791ebe95d0c51d746.tar.bz2 android_system_media-30bf0cc133ecab46b7999ac791ebe95d0c51d746.zip |
audio_route: fix crash with unsupported control types
Check if control type is supported before accessing xxx_value
fields in mixer_state structure.
Also remove unused parameter warning.
Bug: 12871072.
Change-Id: I64c7d5e16728e3502f1fcd0a40658b72ec7acbe7
-rw-r--r-- | audio_route/audio_route.c | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c index 4a449079..d8e41511 100644 --- a/audio_route/audio_route.c +++ b/audio_route/audio_route.c @@ -77,6 +77,18 @@ struct config_parse_state { /* path functions */ +bool is_supported_ctl_type(enum mixer_ctl_type type) +{ + switch (type) { + case MIXER_CTL_TYPE_BOOL: + case MIXER_CTL_TYPE_INT: + case MIXER_CTL_TYPE_ENUM: + return true; + default: + return false; + } +} + static inline struct mixer_ctl *index_to_ctl(struct audio_route *ar, unsigned int ctl_index) { @@ -289,9 +301,15 @@ static int path_apply(struct audio_route *ar, struct mixer_path *path) { unsigned int i; unsigned int ctl_index; + struct mixer_ctl *ctl; + enum mixer_ctl_type type; for (i = 0; i < path->length; i++) { ctl_index = path->setting[i].ctl_index; + ctl = index_to_ctl(ar, ctl_index); + type = mixer_ctl_get_type(ctl); + if (!is_supported_ctl_type(type)) + continue; /* apply the new value(s) */ memcpy(ar->mixer_state[ctl_index].new_value, path->setting[i].value, @@ -306,9 +324,15 @@ static int path_reset(struct audio_route *ar, struct mixer_path *path) unsigned int i; unsigned int j; unsigned int ctl_index; + struct mixer_ctl *ctl; + enum mixer_ctl_type type; for (i = 0; i < path->length; i++) { ctl_index = path->setting[i].ctl_index; + ctl = index_to_ctl(ar, ctl_index); + type = mixer_ctl_get_type(ctl); + if (!is_supported_ctl_type(type)) + continue; /* reset the value(s) */ memcpy(ar->mixer_state[ctl_index].new_value, @@ -347,6 +371,7 @@ static void start_tag(void *data, const XML_Char *tag_name, int value; unsigned int id; struct mixer_value mixer_value; + enum mixer_ctl_type type; /* Get name, id and value attributes (these may be empty) */ for (i = 0; attr[i]; i += 2) { @@ -404,19 +429,22 @@ static void start_tag(void *data, const XML_Char *tag_name, if (state->level == 1) { /* top level ctl (initial setting) */ - /* apply the new value */ - if (attr_id) { - /* set only one value */ - id = atoi((char *)attr_id); - if (id < ar->mixer_state[ctl_index].num_values) - ar->mixer_state[ctl_index].new_value[id] = value; - else - ALOGE("value id out of range for mixer ctl '%s'", - mixer_ctl_get_name(ctl)); - } else { - /* set all values the same */ - for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++) - ar->mixer_state[ctl_index].new_value[i] = value; + type = mixer_ctl_get_type(ctl); + if (is_supported_ctl_type(type)) { + /* apply the new value */ + if (attr_id) { + /* set only one value */ + id = atoi((char *)attr_id); + if (id < ar->mixer_state[ctl_index].num_values) + ar->mixer_state[ctl_index].new_value[id] = value; + else + ALOGE("value id out of range for mixer ctl '%s'", + mixer_ctl_get_name(ctl)); + } else { + /* set all values the same */ + for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++) + ar->mixer_state[ctl_index].new_value[i] = value; + } } } else { /* nested ctl (within a path) */ @@ -437,6 +465,7 @@ done: static void end_tag(void *data, const XML_Char *tag_name) { struct config_parse_state *state = data; + (void)tag_name; state->level--; } @@ -463,8 +492,8 @@ static int alloc_mixer_state(struct audio_route *ar) /* Skip unsupported types that are not supported yet in XML */ type = mixer_ctl_get_type(ctl); - if ((type != MIXER_CTL_TYPE_BOOL) && (type != MIXER_CTL_TYPE_INT) && - (type != MIXER_CTL_TYPE_ENUM)) + + if (!is_supported_ctl_type(type)) continue; ar->mixer_state[i].old_value = malloc(num_values * sizeof(int)); @@ -485,8 +514,13 @@ static int alloc_mixer_state(struct audio_route *ar) static void free_mixer_state(struct audio_route *ar) { unsigned int i; + enum mixer_ctl_type type; for (i = 0; i < ar->num_mixer_ctls; i++) { + type = mixer_ctl_get_type(ar->mixer_state[i].ctl); + if (!is_supported_ctl_type(type)) + continue; + free(ar->mixer_state[i].old_value); free(ar->mixer_state[i].new_value); free(ar->mixer_state[i].reset_value); @@ -511,8 +545,7 @@ int audio_route_update_mixer(struct audio_route *ar) /* Skip unsupported types */ type = mixer_ctl_get_type(ctl); - if ((type != MIXER_CTL_TYPE_BOOL) && (type != MIXER_CTL_TYPE_INT) && - (type != MIXER_CTL_TYPE_ENUM)) + if (!is_supported_ctl_type(type)) continue; /* if the value has changed, update the mixer */ @@ -540,8 +573,13 @@ int audio_route_update_mixer(struct audio_route *ar) static void save_mixer_state(struct audio_route *ar) { unsigned int i; + enum mixer_ctl_type type; for (i = 0; i < ar->num_mixer_ctls; i++) { + type = mixer_ctl_get_type(ar->mixer_state[i].ctl); + if (!is_supported_ctl_type(type)) + continue; + memcpy(ar->mixer_state[i].reset_value, ar->mixer_state[i].new_value, ar->mixer_state[i].num_values * sizeof(int)); } @@ -551,9 +589,14 @@ static void save_mixer_state(struct audio_route *ar) void audio_route_reset(struct audio_route *ar) { unsigned int i; + enum mixer_ctl_type type; /* load all of the saved values */ for (i = 0; i < ar->num_mixer_ctls; i++) { + type = mixer_ctl_get_type(ar->mixer_state[i].ctl); + if (!is_supported_ctl_type(type)) + continue; + memcpy(ar->mixer_state[i].new_value, ar->mixer_state[i].reset_value, ar->mixer_state[i].num_values * sizeof(int)); } |