6893156 zonecfg(1M)'s grammar rejects property names and resource types where it expects property values
authorjv227347 <Jordan.Vaughan@Sun.com>
Mon, 09 Nov 2009 21:09:22 -0800
changeset 11024 16869afd5fb1
parent 11023 53231798f4a8
child 11025 96e66bda9446
6893156 zonecfg(1M)'s grammar rejects property names and resource types where it expects property values
usr/src/cmd/zonecfg/zonecfg.c
usr/src/cmd/zonecfg/zonecfg.h
usr/src/cmd/zonecfg/zonecfg_grammar.y
--- a/usr/src/cmd/zonecfg/zonecfg.c	Mon Nov 09 20:49:09 2009 -0800
+++ b/usr/src/cmd/zonecfg/zonecfg.c	Mon Nov 09 21:09:22 2009 -0800
@@ -154,7 +154,7 @@
 #define	MAX_RT_STRLEN	16
 
 /* These *must* match the order of the RT_ define's from zonecfg.h */
-static char *res_types[] = {
+char *res_types[] = {
 	"unknown",
 	"zonename",
 	"zonepath",
@@ -186,7 +186,7 @@
 };
 
 /* These *must* match the order of the PT_ define's from zonecfg.h */
-static char *prop_types[] = {
+char *prop_types[] = {
 	"unknown",
 	"zonename",
 	"zonepath",
--- a/usr/src/cmd/zonecfg/zonecfg.h	Mon Nov 09 20:49:09 2009 -0800
+++ b/usr/src/cmd/zonecfg/zonecfg.h	Mon Nov 09 21:09:22 2009 -0800
@@ -219,6 +219,8 @@
 extern void usage(boolean_t verbose, uint_t flags);
 
 extern FILE *yyin;
+extern char *res_types[];
+extern char *prop_types[];
 
 #ifdef __cplusplus
 }
--- a/usr/src/cmd/zonecfg/zonecfg_grammar.y	Mon Nov 09 20:49:09 2009 -0800
+++ b/usr/src/cmd/zonecfg/zonecfg_grammar.y	Mon Nov 09 21:09:22 2009 -0800
@@ -26,6 +26,7 @@
  */
 
 #include <stdio.h>
+#include <strings.h>
 
 #include "zonecfg.h"
 
@@ -42,6 +43,72 @@
 extern int yydebug;
 extern void yyerror(char *s);
 
+/*
+ * This function is used by the simple_prop_val reduction rules to set up
+ * a list_property_ptr_t and adjust the above global variables appropriately.
+ * Note that this function duplicates the specified string and makes
+ * the new list's lp_simple field point to the duplicate.  This function does
+ * not free the original string.
+ *
+ * This function returns a pointer to the duplicated string or NULL if an error
+ * occurred.  The simple_prop_val reduction rules that invoke this function
+ * should set $$ to the returned pointer.
+ */
+static char *
+simple_prop_val_func(const char *str)
+{
+	char *retstr;
+
+	if ((new_list = alloc_list()) == NULL)
+		return (NULL);
+	if ((retstr = strdup(str)) == NULL) {
+		free_list(new_list);
+		return (NULL);
+	}
+	new_list->lp_simple = retstr;
+	new_list->lp_complex = NULL;
+	new_list->lp_next = NULL;
+	if (list[num_prop_vals] == NULL) {
+		list[num_prop_vals] = new_list;
+	} else {
+		for (tmp_list = list[num_prop_vals]; tmp_list != NULL;
+		    tmp_list = tmp_list->lp_next)
+			last = tmp_list;
+		last->lp_next = new_list;
+	}
+	return (retstr);
+}
+
+/*
+ * This function is used by the complex_piece reduction rules to set up a
+ * complex_property_prt_t and adjust the above global variables appropriately.
+ * Note that this function duplicates the specified string and makes the new
+ * complex_property_ptr_t's cp_value field point to the duplicate.  It also sets
+ * the complex_property_ptr_t's cp_type field to cp_type and its cp_next field
+ * to cp_next.  This function does not free the original string.
+ *
+ * This function returns a pointer to the complex_property_t created for the
+ * complex_piece or NULL if an error occurred.  The complex_piece reduction
+ * rules that invoke this function should set $$ to the returned pointer.
+ */
+static complex_property_ptr_t
+complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next)
+{
+	complex_property_ptr_t retval;
+
+	if ((retval = alloc_complex()) == NULL)
+		return (NULL);
+	if ((retval->cp_value = strdup(str)) == NULL) {
+		free_complex(retval);
+		return (NULL);
+	}
+	retval->cp_type = cp_type;
+	retval->cp_next = cp_next;
+	complex = retval;
+	return (retval);
+}
+
+
 %}
 
 %union {
@@ -946,23 +1013,28 @@
  * below, and freed by recursive functions which are ultimately called
  * by free_cmd(), which is called from the top-most "commands" part of
  * the grammar.
+ *
+ * NOTE: simple_prop_val and complex_piece need reduction rules for
+ * property_name and resource_type so that the parser will accept property names
+ * and resource type names as property values.
  */
 
 simple_prop_val: TOKEN
 	{
-		if ((new_list = alloc_list()) == NULL)
+		$$ = simple_prop_val_func($1);
+		free($1);
+		if ($$ == NULL)
 			YYERROR;
-		new_list->lp_simple = $1;
-		new_list->lp_complex = NULL;
-		new_list->lp_next = NULL;
-		if (list[num_prop_vals] == NULL) {
-			list[num_prop_vals] = new_list;
-		} else {
-			for (tmp_list = list[num_prop_vals]; tmp_list != NULL;
-			    tmp_list = tmp_list->lp_next)
-				last = tmp_list;
-			last->lp_next = new_list;
-		}
+	}
+	| resource_type
+	{
+		if (($$ = simple_prop_val_func(res_types[$1])) == NULL)
+			YYERROR;
+	}
+	| property_name
+	{
+		if (($$ = simple_prop_val_func(prop_types[$1])) == NULL)
+			YYERROR;
 	}
 
 complex_prop_val: OPEN_PAREN complex_piece CLOSE_PAREN
@@ -984,21 +1056,39 @@
 
 complex_piece: property_name EQUAL TOKEN
 	{
-		if (($$ = alloc_complex()) == NULL)
+		$$ = complex_piece_func($1, $3, NULL);
+		free($3);
+		if ($$ == NULL)
 			YYERROR;
-		$$->cp_type = $1;
-		$$->cp_value = $3;
-		$$->cp_next = NULL;
-		complex = $$;
+	}
+	| property_name EQUAL resource_type
+	{
+		if (($$ = complex_piece_func($1, res_types[$3], NULL)) == NULL)
+			YYERROR;
+	}
+	| property_name EQUAL property_name
+	{
+		if (($$ = complex_piece_func($1, prop_types[$3], NULL)) == NULL)
+			YYERROR;
 	}
 	| property_name EQUAL TOKEN COMMA complex_piece 
 	{
-		if (($$ = alloc_complex()) == NULL)
+		$$ = complex_piece_func($1, $3, complex);
+		free($3);
+		if ($$ == NULL)
 			YYERROR;
-		$$->cp_type = $1;
-		$$->cp_value = $3;
-		$$->cp_next = complex;
-		complex = $$;
+	}
+	| property_name EQUAL resource_type COMMA complex_piece 
+	{
+		if (($$ = complex_piece_func($1, res_types[$3], complex)) ==
+		    NULL)
+			YYERROR;
+	}
+	| property_name EQUAL property_name COMMA complex_piece 
+	{
+		if (($$ = complex_piece_func($1, prop_types[$3], complex)) ==
+		    NULL)
+			YYERROR;
 	}
 
 list_piece: simple_prop_val