[PATCH] Strip quotes and newline when setting STRING parameters.

Christopher Brannon cmbrannon at cox.net
Thu May 28 00:28:20 EDT 2009


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




More information about the Speakup mailing list