- Fixed segfault due to missing check for variable declaration.
authorMichael Meskes
Thu, 4 Mar 2004 07:32:02 +0000 (07:32 +0000)
committerMichael Meskes
Thu, 4 Mar 2004 07:32:02 +0000 (07:32 +0000)
- Added check for multidimensional array usage.

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/variable.c

index 1ef50c177a1d922751d2b70b46a319aca5dfa78f..922def7031e12f29c67066e1b9965d383acdaa46 100644 (file)
@@ -1754,6 +1754,11 @@ Tue Feb 24 16:48:57 CET 2004
 Mon Mar  1 08:56:37 CET 2004
    
    - Added partly missing VOLATILE keyword.
+   
+Thu Mar  4 08:29:02 CET 2004
+
+   - Fixed segfault due to missing check for variable declaration.
+   - Added check for multidimensional array usage.
    - Set pgtypeslib version to 1.2.
    - Set ecpg version to 3.2.0.
 
index 3e106f3bbc2282c278d169c79c843b9deac6a742..96f3bb074b02995fc76b1cf8854e09167438bd3a 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.276 2004/03/02 06:45:05 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.277 2004/03/04 07:32:01 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -541,7 +541,7 @@ add_additional_variables(char *name, bool insert)
 %type     ECPGTypeName using_list ECPGColLabelCommon UsingConst
 %type     inf_val_list inf_col_list using_descriptor into_descriptor 
 %type     ecpg_into_using prepared_name struct_union_type_with_symbol
-%type     ECPGunreserved ECPGunreserved_interval
+%type     ECPGunreserved ECPGunreserved_interval cvariable
 
 %type   s_struct_union_symbol
 
@@ -4220,7 +4220,7 @@ connection_target: database_name opt_server opt_port
        }
        ;
 
-db_prefix: ident CVARIABLE
+db_prefix: ident cvariable
        {
            if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
            {
@@ -4311,7 +4311,7 @@ user_name: UserId
        }
        ;
 
-char_variable: CVARIABLE
+char_variable: cvariable
        {
            /* check if we have a char variable */
            struct variable *p = find_variable($1);
@@ -5241,14 +5241,14 @@ ECPGAllocateDescr:  SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
  * read from descriptor
  */
 
-ECPGGetDescHeaderItem: CVARIABLE '=' desc_header_item
+ECPGGetDescHeaderItem: cvariable '=' desc_header_item
            { push_assignment($1, $3); }
        ;
 
 desc_header_item:  SQL_COUNT           { $$ = ECPGd_count; }
        ;
 
-ECPGGetDescItem: CVARIABLE '=' descriptor_item { push_assignment($1, $3); };
+ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); };
 
 descriptor_item:   SQL_CARDINALITY     { $$ = ECPGd_cardinality; }
        | SQL_DATA                      { $$ = ECPGd_data; }
@@ -5280,7 +5280,7 @@ ECPGGetDescriptorHeader:  GET SQL_DESCRIPTOR quoted_ident_stringvar
            {  $$ = $3; }
        ;
 
-ECPGGetDescriptor: GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE CVARIABLE ECPGGetDescItems
+ECPGGetDescriptor: GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvariable ECPGGetDescItems
            {  $$.str = $5; $$.name = $3; }
        |   GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGGetDescItems
            {  $$.str = $5; $$.name = $3; }
@@ -6047,14 +6047,14 @@ c_args: /*EMPTY*/       { $$ = EMPTY; }
        | c_list        { $$ = $1; }
        ;
 
-coutputvariable: CVARIABLE indicator
+coutputvariable: cvariable indicator
            { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
-       | CVARIABLE
+       | cvariable
            { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
        ;
 
 
-civarind: CVARIABLE indicator
+civarind: cvariable indicator
        {
            if (find_variable($2)->type->type == ECPGt_array)
                mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
@@ -6064,18 +6064,47 @@ civarind: CVARIABLE indicator
        }
        ;
 
-civar: CVARIABLE
+civar: cvariable
            {
                add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
                $$ = create_questionmarks($1, false);
            }
        ;
 
-indicator: CVARIABLE               { check_indicator((find_variable($1))->type); $$ = $1; }
-       | SQL_INDICATOR CVARIABLE   { check_indicator((find_variable($2))->type); $$ = $2; }
+indicator: cvariable               { check_indicator((find_variable($1))->type); $$ = $1; }
+       | SQL_INDICATOR cvariable   { check_indicator((find_variable($2))->type); $$ = $2; }
        | SQL_INDICATOR name        { check_indicator((find_variable($2))->type); $$ = $2; }
        ;
 
+cvariable: CVARIABLE 
+       {
+           /* As long as multidimensional arrays are not implemented we have to check for those here */
+           char *ptr = $1;
+           int brace_open=0, brace = false;
+           
+           for (; *ptr; ptr++)
+           {
+               switch (*ptr)
+               {
+                   case '[':   if (brace)
+                           {
+                               mmerror(PARSE_ERROR, ET_FATAL, "No multidimensional array support for simple data types");
+                           }
+                           brace_open++;
+                           break;
+                   case ']':   brace_open--;
+                           if (brace_open == 0) brace = true;
+                           break;
+                   case '\t':
+                   case ' ':   break;
+                   default:    if (brace_open == 0) brace = false;
+                           break;
+               }
+           }
+
+           $$ = $1;
+       }
+       ;
 ident: IDENT                   { $$ = $1; }
        | CSTRING           { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
        ;
index e12b94349980edbf2fa59069b729197bc5d050d6..f1a875f0ccccfaa5c1402091f522845353e05b2b 100644 (file)
@@ -218,7 +218,7 @@ find_variable(char *name)
        {
            /*
             * We don't care about what's inside the array braces so just
-            * eat up the character
+            * eat up the characters
             */
            for (count = 1, end = next + 1; count; end++)
            {
@@ -242,6 +242,11 @@ find_variable(char *name)
 
                *next = '\0';
                p = find_simple(name);
+               if (p == NULL)
+               {
+                   snprintf(errortext, sizeof(errortext), "The variable %s is not declared", name);
+                   mmerror(PARSE_ERROR, ET_FATAL, errortext);
+               }              
                *next = c;
                switch (p->type->u.element->type)
                {