diff --git a/src/lib/sdl/audio/SDL_genodeaudio.cc b/src/lib/sdl/audio/SDL_genodeaudio.cc index 699668c..2d50716 100644 --- a/src/lib/sdl/audio/SDL_genodeaudio.cc +++ b/src/lib/sdl/audio/SDL_genodeaudio.cc @@ -79,12 +79,10 @@ struct Volume_config Genode::Xml_node config = _config_rom.xml(); - try { - unsigned int config_volume; - config.sub_node("sdl_audio_volume").attribute("value") - .value(&config_volume); - volume = (float)config_volume / 100; - } catch (...) { } + config.with_sub_node("sdl_audio_volume", [&] (Genode::Xml_node const &node) { + volume = (float)node.attribute_value("value", (unsigned)(volume*100)) + / 100; + }); Genode::log("Change SDL audio volume to ", volume * 100); } diff --git a/src/lib/sdl/sdl_main.cc b/src/lib/sdl/sdl_main.cc index 53a03cf..2b34dfc 100644 --- a/src/lib/sdl/sdl_main.cc +++ b/src/lib/sdl/sdl_main.cc @@ -74,14 +74,20 @@ void Libc::Component::construct(Libc::Env &env) int arg_i = 0; int env_i = 0; node.for_each_sub_node([&] (Xml_node const &node) { + /* insert an argument */ if (node.has_type("arg")) try { + Xml_attribute attr = node.attribute("value"); + attr.with_raw_value([&] (char const *start, size_t length) { - Genode::size_t const arg_len = attr.value_size()+1; - char *arg = argv[arg_i] = (char*)malloc(arg_len); + size_t const size = length + 1; /* for null termination */ + + argv[arg_i] = (char *)malloc(size); + + Genode::copy_cstring(argv[arg_i], start, size); + }); - attr.value(arg, arg_len); ++arg_i; } catch (Xml_node::Nonexistent_sub_node) { } @@ -90,22 +96,56 @@ void Libc::Component::construct(Libc::Env &env) /* insert an environment variable */ if (node.has_type("env")) try { - Xml_attribute key_attr = node.attribute("key"); - Xml_attribute val_attr = node.attribute("value"); - Genode::size_t const pair_len = - key_attr.value_size() + - val_attr.value_size() + 1; - char *env = envp[env_i] = (char*)malloc(pair_len); + auto check_attr = [] (Xml_node node, auto key) { + if (!node.has_attribute(key)) + Genode::warning(" node lacks '", key, "' attribute"); }; + + check_attr(node, "key"); + check_attr(node, "value"); + + Xml_attribute const key = node.attribute("key"); + Xml_attribute const value = node.attribute("value"); + + using namespace Genode; + + /* + * An environment variable has the form =, followed + * by a terminating zero. + */ + size_t const var_size = key .value_size() + 1 + + value.value_size() + 1; + + envp[env_i] = (char*)malloc(var_size); + + size_t pos = 0; + + /* append characters to env variable with zero termination */ + auto append = [&] (char const *s, size_t len) { + + if (pos + len >= var_size) { + /* this should never happen */ + warning("truncated environment variable: ", node); + return; + } + + copy_cstring(envp[env_i] + pos, s, len + 1); + pos += len; + }; + + key.with_raw_value([&] (char const *start, size_t length) { + append(start, length); }); + + append("=", 1); + + value.with_raw_value([&] (char const *start, size_t length) { + append(start, length); }); - Genode::size_t off = 0; - key_attr.value(&env[off], key_attr.value_size()+1); - off = key_attr.value_size(); - env[off++] = '='; - val_attr.value(&env[off], val_attr.value_size()+1); ++env_i; - } catch (Xml_node::Nonexistent_sub_node) { } + } + catch (Xml_node::Nonexistent_sub_node) { } + catch (Xml_node::Nonexistent_attribute) { } }); envp[env_i] = NULL;