Blame SOURCES/autofs-5.1.3-fix-amd-parser-double-quote-handling.patch

cef8f8
autofs-5.1.3 - fix amd parser double quote handling
cef8f8
cef8f8
From: Ian Kent <raven@themaw.net>
cef8f8
cef8f8
While the natuaral usage of amd maps doesn't use double quotes
cef8f8
it is allowed to use them to enclose option values.
cef8f8
cef8f8
The options mount, umount and unmount usually require them to
cef8f8
preserve spaces in the option value.
cef8f8
cef8f8
Signed-off-by: Ian Kent <raven@themaw.net>
cef8f8
---
cef8f8
 CHANGELOG           |    1 
cef8f8
 modules/amd_parse.y |  150 ++++++++++++++++++++++++++++++++++++++++++++--------
cef8f8
 modules/amd_tok.l   |    4 +
cef8f8
 3 files changed, 132 insertions(+), 23 deletions(-)
cef8f8
cef8f8
--- autofs-5.0.7.orig/CHANGELOG
cef8f8
+++ autofs-5.0.7/CHANGELOG
cef8f8
@@ -274,6 +274,7 @@
cef8f8
 - remove expand_selectors() on amd parser entry.
cef8f8
 - fix amd defaults map entry handling.
cef8f8
 - refactor amd_parse.c.
cef8f8
+- fix amd parser double quote handling.
cef8f8
 
cef8f8
 25/07/2012 autofs-5.0.7
cef8f8
 =======================
cef8f8
--- autofs-5.0.7.orig/modules/amd_parse.y
cef8f8
+++ autofs-5.0.7/modules/amd_parse.y
cef8f8
@@ -99,6 +99,7 @@ static int amd_fprintf(FILE *, char *, .
cef8f8
 %token CUT
cef8f8
 %token NOT_EQUAL
cef8f8
 %token COMMA
cef8f8
+%token QUOTE
cef8f8
 %token OPTION_ASSIGN
cef8f8
 %token LBRACKET
cef8f8
 %token RBRACKET
cef8f8
@@ -268,62 +269,114 @@ option_assignment: MAP_OPTION OPTION_ASS
cef8f8
 	}
cef8f8
 	| MAP_OPTION OPTION_ASSIGN FS_OPT_VALUE
cef8f8
 	{
cef8f8
-		if (!strcmp($1, "fs"))
cef8f8
-			entry.fs = amd_strdup($3);
cef8f8
-		else if (!strcmp($1, "sublink"))
cef8f8
-			entry.sublink = amd_strdup($3);
cef8f8
-		else if (!strcmp($1, "pref")) {
cef8f8
-			if (!strcmp($3, "null"))
cef8f8
-				entry.pref = amd_strdup("");
cef8f8
-			else
cef8f8
-				entry.pref = amd_strdup($3);
cef8f8
+		/* Quoted value for type, maptype or cache assign */
cef8f8
+		if (!strcmp($1, "type")) {
cef8f8
+			if (!match_map_option_fs_type($1, $3))
cef8f8
+				YYABORT;
cef8f8
+		} else if (!strcmp($1, "maptype")) {
cef8f8
+			if (!match_map_option_map_type($1, $3))
cef8f8
+				YYABORT;
cef8f8
+		} else if (!strcmp($1, "cache")) {
cef8f8
+			if (!match_map_option_cache_option($3))
cef8f8
+				YYABORT;
cef8f8
 		} else {
cef8f8
-			amd_notify($1);
cef8f8
-			YYABORT;
cef8f8
+			char *fs_opt_val;
cef8f8
+
cef8f8
+			fs_opt_val = amd_strdup($3);
cef8f8
+			if (!fs_opt_val) {
cef8f8
+				amd_notify($3);
cef8f8
+				YYABORT;
cef8f8
+			}
cef8f8
+
cef8f8
+			if (!strcmp($1, "fs"))
cef8f8
+				entry.fs = fs_opt_val;
cef8f8
+			else if (!strcmp($1, "sublink")) {
cef8f8
+				entry.sublink = fs_opt_val;
cef8f8
+			} else if (!strcmp($1, "pref")) {
cef8f8
+				if (strcmp(fs_opt_val, "null"))
cef8f8
+					entry.pref = fs_opt_val;
cef8f8
+				else {
cef8f8
+					entry.pref = amd_strdup("");
cef8f8
+					if (!entry.pref) {
cef8f8
+						amd_notify($3);
cef8f8
+						free(fs_opt_val);
cef8f8
+						YYABORT;
cef8f8
+					}
cef8f8
+					free(fs_opt_val);
cef8f8
+				}
cef8f8
+			} else {
cef8f8
+				amd_notify($1);
cef8f8
+				free(fs_opt_val);
cef8f8
+				YYABORT;
cef8f8
+			}
cef8f8
 		}
cef8f8
 	}
cef8f8
 	| MAP_OPTION OPTION_ASSIGN
cef8f8
 	{
cef8f8
-		if (!strcmp($1, "fs"))
cef8f8
+		if (!strcmp($1, "fs")) {
cef8f8
 			entry.fs = amd_strdup("");
cef8f8
-		else {
cef8f8
+			if (!entry.fs) {
cef8f8
+				amd_notify($1);
cef8f8
+				YYABORT;
cef8f8
+			}
cef8f8
+		} else {
cef8f8
 			amd_notify($1);
cef8f8
 			YYABORT;
cef8f8
 		}
cef8f8
 	}
cef8f8
 	| FS_OPTION OPTION_ASSIGN FS_OPT_VALUE
cef8f8
 	{
cef8f8
+		char *fs_opt_val;
cef8f8
+
cef8f8
+		fs_opt_val = amd_strdup($3);
cef8f8
+		if (!fs_opt_val) {
cef8f8
+			amd_notify($1);
cef8f8
+			YYABORT;
cef8f8
+		}
cef8f8
+
cef8f8
 		if (!strcmp($1, "rhost"))
cef8f8
-			entry.rhost = amd_strdup($3);
cef8f8
+			entry.rhost = fs_opt_val;
cef8f8
 		else if (!strcmp($1, "rfs"))
cef8f8
-			entry.rfs = amd_strdup($3);
cef8f8
+			entry.rfs = fs_opt_val;
cef8f8
 		else if (!strcmp($1, "dev"))
cef8f8
-			entry.dev = amd_strdup($3);
cef8f8
+			entry.dev = fs_opt_val;
cef8f8
 		else if (!strcmp($1, "mount") ||
cef8f8
 			 !strcmp($1, "unmount") ||
cef8f8
 			 !strcmp($1, "umount")) {
cef8f8
 			amd_info("file system type program is not "
cef8f8
 				 "yet implemented, option ignored");
cef8f8
+			free(fs_opt_val);
cef8f8
 			YYABORT;
cef8f8
 		} else if (!strcmp($1, "delay") ||
cef8f8
 			   !strcmp($1, "cachedir")) {
cef8f8
 			sprintf(msg_buf, "option %s is not used by autofs", $1);
cef8f8
 			amd_info(msg_buf);
cef8f8
+			free(fs_opt_val);
cef8f8
 		} else {
cef8f8
 			amd_notify($1);
cef8f8
+			free(fs_opt_val);
cef8f8
 			YYABORT;
cef8f8
 		}
cef8f8
 	}
cef8f8
 	| FS_OPTION OPTION_ASSIGN
cef8f8
 	{
cef8f8
+		char *empty;
cef8f8
+
cef8f8
+		empty = amd_strdup("");
cef8f8
+		if (!empty) {
cef8f8
+			amd_notify($1);
cef8f8
+			YYABORT;
cef8f8
+		}
cef8f8
+
cef8f8
 		if (!strcmp($1, "rhost"))
cef8f8
-			entry.rhost = amd_strdup("");
cef8f8
+			entry.rhost = empty;
cef8f8
 		else if (!strcmp($1, "rfs"))
cef8f8
-			entry.rfs = amd_strdup("");
cef8f8
+			entry.rfs = empty;
cef8f8
 		else if (!strcmp($1, "dev"))
cef8f8
-			entry.dev = amd_strdup("");
cef8f8
+			entry.dev = empty;
cef8f8
 		else {
cef8f8
 			amd_notify($1);
cef8f8
+			free(empty);
cef8f8
 			YYABORT;
cef8f8
 		}
cef8f8
 	}
cef8f8
@@ -335,6 +388,14 @@ option_assignment: MAP_OPTION OPTION_ASS
cef8f8
 		}
cef8f8
 		memset(opts, 0, sizeof(opts));
cef8f8
 	}
cef8f8
+	| MNT_OPTION OPTION_ASSIGN QUOTE options QUOTE
cef8f8
+	{
cef8f8
+		if (!match_mnt_option_options($1, $4)) {
cef8f8
+			amd_notify($1);
cef8f8
+			YYABORT;
cef8f8
+		}
cef8f8
+		memset(opts, 0, sizeof(opts));
cef8f8
+	}
cef8f8
 	| MNT_OPTION OPTION_ASSIGN
cef8f8
 	{
cef8f8
 		memset(opts, 0, sizeof(opts));
cef8f8
@@ -601,11 +662,56 @@ static int amd_fprintf(FILE *f, char *ms
cef8f8
 
cef8f8
 static char *amd_strdup(char *str)
cef8f8
 {
cef8f8
+	unsigned int quoted, len;
cef8f8
 	char *tmp;
cef8f8
 
cef8f8
-	tmp = strdup(str);
cef8f8
-	if (!tmp)
cef8f8
-		amd_error("memory allocation error");
cef8f8
+	len = strlen(str);
cef8f8
+	quoted = 0;
cef8f8
+
cef8f8
+	if (*str == '"') {
cef8f8
+		quoted = 1;
cef8f8
+		len -= 2;
cef8f8
+	}
cef8f8
+
cef8f8
+	tmp = strdup(str + quoted);
cef8f8
+	if (!tmp) {
cef8f8
+		amd_msg("memory allocation error");
cef8f8
+		return NULL;
cef8f8
+	} else {
cef8f8
+		unsigned int squote;
cef8f8
+		char *ptr;
cef8f8
+
cef8f8
+		if (quoted) {
cef8f8
+			if (tmp[len] != '"') {
cef8f8
+				sprintf(msg_buf,
cef8f8
+					"unmatched double quote near: %s", str);
cef8f8
+				amd_info(msg_buf);
cef8f8
+				free(tmp);
cef8f8
+				return NULL;
cef8f8
+			}
cef8f8
+			tmp[len] = 0;
cef8f8
+		}
cef8f8
+
cef8f8
+		/* Check for matching single quotes */
cef8f8
+		if (!strchr(tmp, 39))
cef8f8
+			goto done;
cef8f8
+
cef8f8
+		ptr = tmp;
cef8f8
+		squote = 0;
cef8f8
+		while (*ptr) {
cef8f8
+			if (*ptr == 39)
cef8f8
+				squote = !squote;
cef8f8
+			ptr++;
cef8f8
+		}
cef8f8
+		if (squote) {
cef8f8
+			sprintf(msg_buf,
cef8f8
+				"unmatched single quote near: %s", str);
cef8f8
+			amd_info(msg_buf);
cef8f8
+			free(tmp);
cef8f8
+			return NULL;
cef8f8
+		}
cef8f8
+	}
cef8f8
+done:
cef8f8
 	return tmp;
cef8f8
 }
cef8f8
 
cef8f8
--- autofs-5.0.7.orig/modules/amd_tok.l
cef8f8
+++ autofs-5.0.7/modules/amd_tok.l
cef8f8
@@ -94,7 +94,7 @@ IP6ADDR		((([A-Fa-f0-9]{1,4}\:\:?){1,7}[
cef8f8
 V6MASK		(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[1-9])
cef8f8
 
cef8f8
 FOPT		(({QSTR}|{FSTR}|{MACRO})+)
cef8f8
-OPTS		({OSTR}(=({VSTR}|{QSTR}|{MACRO})+)?)
cef8f8
+OPTS		({OSTR}(=({VSTR}|{MACRO})+)?)
cef8f8
 SOPT		(({SSTR}|{QSTR}|{MACRO})+)
cef8f8
 NOPT		({SSTR}|(({IP4ADDR}(\/{V4MASK})?)|({IP6ADDR}(\/{V6MASK})?)))
cef8f8
 
cef8f8
@@ -288,6 +288,8 @@ CUTSEP		(\|\||\/)
cef8f8
 
cef8f8
 	,+ { return COMMA; }
cef8f8
 
cef8f8
+	"\"" { return QUOTE; }
cef8f8
+
cef8f8
 	{OPTS} {
cef8f8
 		amd_copy_buffer();
cef8f8
 		return OPTION;