When the user reads the contents of a STRING parameter via sysfs, Speakup surrounds the data with a balanced pair of quotes. Example: "\x01+3p" The kernel appends a newline. When the user tries to set a parameter via sysfs, Speakup should strip away the newline and balanced quotes. Thus, reads and writes of files under /sys/modules/speakup/parameters should be inverses of one another. This patch guarantees such behavior. --- src/paramhelpers.c | 2 +- src/varhandlers.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/paramhelpers.c b/src/paramhelpers.c index 7dbd060..1bbfe17 100644 --- a/src/paramhelpers.c +++ b/src/paramhelpers.c @@ -755,8 +755,8 @@ static int set_vars(const char *val, struct kernel_param *kp) return 0; ret = 0; - len = strlen(val); cp = xlate((char *) val); + len = strlen(val); /* xlate may have changed the length of the string */ switch (param->var_type) { case VAR_NUM: case VAR_TIME: diff --git a/src/varhandlers.c b/src/varhandlers.c index a79b03a..1c3d1f5 100644 --- a/src/varhandlers.c +++ b/src/varhandlers.c @@ -240,6 +240,20 @@ int set_string_var(const char *page, struct st_var_header *var, int len) struct var_t *var_data = var->data; if (var_data == NULL) return E_UNDEF; + + /* + * The user might supply a parameter as "param"<newline>, because + * this is the representation that Speakup uses when producing data + * for the STRING parameter files under /sys. Snip the balanced + * quotes and newline, if present. + */ + + if((len >= 1) && (page[len - 1] == '\n')) + --len; + if((len >= 2) && (page[0] == '"') && (page[len - 1] == '"')) { + ++page; + len -= 2; /* balanced pair of quotes */ + } if (len > MAXVARLEN) return -E_TOOLONG; if (!len) { @@ -250,8 +264,10 @@ int set_string_var(const char *page, struct st_var_header *var, int len) var->p_val = var_data->u.s.default_val; if (var->p_val != var_data->u.s.default_val) strcpy((char *)var->p_val, var_data->u.s.default_val); - } else if (var->p_val) - strcpy((char *)var->p_val, page); + } else if (var->p_val) { + strncpy((char *)var->p_val, page, len); + ((char *) var->p_val)[len] = '\0'; + } else return -E_TOOLONG; return ret; -- 1.6.3.1