Fix buffer-overrun problem in pretty printer.
authorTom Lane
Wed, 19 Dec 2001 22:35:35 +0000 (22:35 +0000)
committerTom Lane
Wed, 19 Dec 2001 22:35:35 +0000 (22:35 +0000)
src/backend/nodes/print.c

index 0e33a99d53d44954be2b48b32fa77490a9e9dc1b..3e362988d9a697e569e315d14edd62a9e1798d75 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.49 2001/10/25 05:49:31 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.50 2001/12/19 22:35:35 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -41,6 +41,7 @@ print(void *obj)
    s = nodeToString(obj);
    printf("%s\n", s);
    fflush(stdout);
+   pfree(s);
 }
 
 /*
@@ -49,59 +50,77 @@ print(void *obj)
 void
 pprint(void *obj)
 {
+#define INDENTSTOP 3
+#define MAXINDENT  60
+#define LINELEN        80
    char       *s;
    int         i;
-   char        line[80];
+   char        line[LINELEN];
    int         indentLev;
+   int         indentDist;
    int         j;
 
    s = nodeToString(obj);
 
-   indentLev = 0;
+   indentLev = 0;              /* logical indent level */
+   indentDist = 0;             /* physical indent distance */
    i = 0;
    for (;;)
    {
-       for (j = 0; j < indentLev * 3; j++)
+       for (j = 0; j < indentDist; j++)
            line[j] = ' ';
-       for (; j < 75 && s[i] != '\0'; i++, j++)
+       for (; j < LINELEN-1 && s[i] != '\0'; i++, j++)
        {
            line[j] = s[i];
            switch (line[j])
            {
                case '}':
-                   if (j != indentLev * 3)
+                   if (j != indentDist)
                    {
+                       /* print data before the } */
                        line[j] = '\0';
                        printf("%s\n", line);
-                       line[indentLev * 3] = '\0';
-                       printf("%s}\n", line);
                    }
-                   else
+                   /* print the } at indentDist */
+                   line[indentDist] = '\0';
+                   printf("%s}\n", line);
+                   /* outdent */
+                   if (indentLev > 0)
                    {
-                       line[j] = '\0';
-                       printf("%s}\n", line);
+                       indentLev--;
+                       indentDist = MIN(indentLev * INDENTSTOP, MAXINDENT);
                    }
-                   indentLev--;
-                   j = indentLev * 3 - 1;      /* print the line before :
-                                                * and resets */
+                   j = indentDist - 1;
+                   /* j will equal indentDist on next loop iteration */
                    break;
                case ')':
+                   /* force line break after ')' */
                    line[j + 1] = '\0';
                    printf("%s\n", line);
-                   j = indentLev * 3 - 1;
+                   j = indentDist - 1;
                    break;
                case '{':
+                   /* force line break before { */
+                   if (j != indentDist)
+                   {
+                       line[j] = '\0';
+                       printf("%s\n", line);
+                   }
+                   /* indent */
                    indentLev++;
-                   /* !!! FALLS THROUGH */
+                   indentDist = MIN(indentLev * INDENTSTOP, MAXINDENT);
+                   for (j = 0; j < indentDist; j++)
+                       line[j] = ' ';
+                   line[j] = s[i];
+                   break;
                case ':':
-                   if (j != 0)
+                   /* force line break before : */
+                   if (j != indentDist)
                    {
                        line[j] = '\0';
                        printf("%s\n", line);
-                       /* print the line before : and resets */
-                       for (j = 0; j < indentLev * 3; j++)
-                           line[j] = ' ';
                    }
+                   j = indentDist;
                    line[j] = s[i];
                    break;
            }
@@ -114,7 +133,7 @@ pprint(void *obj)
    if (j != 0)
        printf("%s\n", line);
    fflush(stdout);
-   return;
+   pfree(s);
 }
 
 /*
@@ -378,7 +397,7 @@ void
 print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
 {
    int         i;
-   char        extraInfo[100];
+   char        extraInfo[NAMEDATALEN + 100];
 
    if (!p)
        return;