]> granicus.if.org Git - python/commitdiff
Add new parser error code, E_OVERFLOW. This error is returned when
authorJeremy Hylton <jeremy@alum.mit.edu>
Tue, 20 Jun 2000 19:10:44 +0000 (19:10 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Tue, 20 Jun 2000 19:10:44 +0000 (19:10 +0000)
the number of children of a node exceeds the max possible value for
the short that is used to count them.  The Python runtime converts
this parser error into the SyntaxError "expression too long."

Include/errcode.h
Include/node.h
Parser/node.c
Parser/parser.c
Python/pythonrun.c

index 565578269afda362cb14c4aa9d6358a54c4d0eb3..f94c11c02ced69addecbb0a51a6fa022ab85d818 100644 (file)
@@ -52,6 +52,7 @@ PERFORMANCE OF THIS SOFTWARE.
 #define E_DONE         16      /* Parsing complete */
 #define E_ERROR                17      /* Execution error */
 #define E_INDENT       18      /* Invalid indentation detected */
+#define E_OVERFLOW      19      /* Node had too many children */
 
 #ifdef __cplusplus
 }
index 7f30923b5a05bf2e16c3c4619177774655f0b692..3a564f7821321ae6e915f8983a66a28356a2c403 100644 (file)
@@ -46,7 +46,7 @@ typedef struct _node {
 } node;
 
 extern DL_IMPORT(node *) PyNode_New Py_PROTO((int type));
-extern DL_IMPORT(node *) PyNode_AddChild Py_PROTO((node *n, int type, char *str, int lineno));
+extern DL_IMPORT(int) PyNode_AddChild Py_PROTO((node *n, int type, char *str, int lineno));
 extern DL_IMPORT(void) PyNode_Free Py_PROTO((node *n));
 
 /* Node access functions */
index c2308fddee705b0513d0ad999cbeb7f74abaace5..3f593c8fde34658e67295b84e4feb49eb09c5a44 100644 (file)
@@ -29,10 +29,13 @@ PERFORMANCE OF THIS SOFTWARE.
 
 ******************************************************************/
 
+#include <limits.h>
+
 /* Parse tree node implementation */
 
 #include "pgenheaders.h"
 #include "node.h"
+#include "errcode.h"
 
 node *
 PyNode_New(type)
@@ -52,7 +55,7 @@ PyNode_New(type)
 #define XXX 3 /* Node alignment factor to speed up realloc */
 #define XXXROUNDUP(n) ((n) == 1 ? 1 : ((n) + XXX - 1) / XXX * XXX)
 
-node *
+int
 PyNode_AddChild(n1, type, str, lineno)
        register node *n1;
        int type;
@@ -62,12 +65,14 @@ PyNode_AddChild(n1, type, str, lineno)
        register int nch = n1->n_nchildren;
        register int nch1 = nch+1;
        register node *n;
+       if (nch == SHRT_MAX || nch < 0)
+               return E_OVERFLOW;
        if (XXXROUNDUP(nch) < nch1) {
                n = n1->n_child;
                nch1 = XXXROUNDUP(nch1);
                PyMem_RESIZE(n, node, nch1);
                if (n == NULL)
-                       return NULL;
+                       return E_NOMEM;
                n1->n_child = n;
        }
        n = &n1->n_child[n1->n_nchildren++];
@@ -76,7 +81,7 @@ PyNode_AddChild(n1, type, str, lineno)
        n->n_lineno = lineno;
        n->n_nchildren = 0;
        n->n_child = NULL;
-       return n;
+       return 0;
 }
 
 /* Forward */
index 3b75dbc3f4d2b9955f16d9b418bbd82c83ba94e0..00299afe70c72be24dd4294c84e4f4124f86a3b0 100644 (file)
@@ -153,11 +153,11 @@ shift(s, type, str, newstate, lineno)
        int newstate;
        int lineno;
 {
+       int err;
        assert(!s_empty(s));
-       if (PyNode_AddChild(s->s_top->s_parent, type, str, lineno) == NULL) {
-               fprintf(stderr, "shift: no mem in addchild\n");
-               return -1;
-       }
+       err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno);
+       if (err)
+               return err;
        s->s_top->s_state = newstate;
        return 0;
 }
@@ -172,13 +172,13 @@ push(s, type, d, newstate, lineno)
        int newstate;
        int lineno;
 {
+       int err;
        register node *n;
        n = s->s_top->s_parent;
        assert(!s_empty(s));
-       if (PyNode_AddChild(n, type, (char *)NULL, lineno) == NULL) {
-               fprintf(stderr, "push: no mem in addchild\n");
-               return -1;
-       }
+       err = PyNode_AddChild(n, type, (char *)NULL, lineno);
+       if (err)
+               return err;
        s->s_top->s_state = newstate;
        return s_push(s, d, CHILD(n, NCH(n)-1));
 }
@@ -233,6 +233,7 @@ PyParser_AddToken(ps, type, str, lineno)
        int lineno;
 {
        register int ilabel;
+       int err;
        
        D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str));
        
@@ -260,20 +261,20 @@ PyParser_AddToken(ps, type, str, lineno)
                                        int arrow = x & ((1<<7)-1);
                                        dfa *d1 = PyGrammar_FindDFA(
                                                ps->p_grammar, nt);
-                                       if (push(&ps->p_stack, nt, d1,
-                                               arrow, lineno) < 0) {
+                                       if ((err = push(&ps->p_stack, nt, d1,
+                                               arrow, lineno)) > 0) {
                                                D(printf(" MemError: push\n"));
-                                               return E_NOMEM;
+                                               return err;
                                        }
                                        D(printf(" Push ...\n"));
                                        continue;
                                }
                                
                                /* Shift the token */
-                               if (shift(&ps->p_stack, type, str,
-                                               x, lineno) < 0) {
+                               if ((err = shift(&ps->p_stack, type, str,
+                                               x, lineno)) > 0) {
                                        D(printf(" MemError: shift.\n"));
-                                       return E_NOMEM;
+                                       return err;
                                }
                                D(printf(" Shift.\n"));
                                /* Pop while we are in an accept-only state */
index 77607146546de20654d99da639149e700c721468..3a60e4724661aa5dd3812caba7a93c28d14c3771 100644 (file)
@@ -1033,6 +1033,9 @@ err_input(err)
        case E_INDENT:
                msg = "inconsistent use of tabs and spaces in indentation";
                break;
+       case E_OVERFLOW:
+               msg = "expression too long";
+               break;
        default:
                fprintf(stderr, "error=%d\n", err->error);
                msg = "unknown parsing error";