Changeset: 95157c648a89 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=95157c648a89
Modified Files:
        monetdb5/mal/mal_listing.c
Branch: default
Log Message:

Check whether data fits before it's too late.
Also, don't allocate a ridiculous amount of memory for a formatted
instruction (no need to base it on the size of the complete plan).
Another GDKfatal bites the dust.


diffs (truncated from 415 to 300 lines):

diff --git a/monetdb5/mal/mal_listing.c b/monetdb5/mal/mal_listing.c
--- a/monetdb5/mal/mal_listing.c
+++ b/monetdb5/mal/mal_listing.c
@@ -32,6 +32,31 @@
 */
 #define advance(X,B,L)  while(*(X) && B+L>X)(X)++;
 
+/* Copy string in src to *dstp which has *lenp space available and
+ * terminate with a NULL byte.  *dstp and *lenp are adjusted for the
+ * used space.  If there is not enough space to copy all of src,
+ * return false, otherwise return true.  The resulting string is
+ * always NULL-terminated. */
+static inline bool
+copystring(char **dstp, const char *src, size_t *lenp)
+{
+       size_t len = *lenp;
+       char *dst = *dstp;
+
+       if (src == NULL)
+               return true;
+       if (len > 0) {
+               while (*src && len > 1) {
+                       *dst++ = *src++;
+                       len--;
+               }
+               *dst = 0;
+               *dstp = dst;
+               *lenp = len;
+       }
+       return *src == 0;
+}
+
 static str
 renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg)
 {
@@ -140,87 +165,80 @@ beginning of each line.
 */
 
 str
-fcnDefinition(MalBlkPtr mb, InstrPtr p, str s, int flg, str base, size_t len)
+fcnDefinition(MalBlkPtr mb, InstrPtr p, str t, int flg, str base, size_t len)
 {
        int i;
-       str arg, t, tpe;
+       str arg, tpe;
 
-       t = s;
-       snprintf(t,(len-(t-base)), "%s", (flg ? "" : "#") );
-       advance(t, base, len);
-       if( mb->inlineProp){
-               snprintf(t,(len-(t-base)), "inline ");
-               advance(t, base, len);
-       }
-       if( mb->unsafeProp){
-               snprintf(t,(len-(t-base)), "unsafe ");
-               advance(t, base, len);
-       }
-       if( mb->sealedProp){
-               snprintf(t,(len-(t-base)), "sealed ");
-               advance(t, base, len);
-       }
-       snprintf(t,(len-(t-base)), "%s ",  operatorName(p->token));
-
-       advance(t, base, len);
-       snprintf(t, (len-(t-base)),  "%s.",  
getModuleId(p)?getModuleId(p):"user");
-       advance(t, base, len);
-       snprintf(t, (len-(t-base)), "%s(",  getFunctionId(p));
-       advance(t, base, len);
+       len -= t - base;
+       if (!flg && !copystring(&t, "#", &len))
+               return base;
+       if( mb->inlineProp && !copystring(&t, "inline ", &len))
+               return base;
+       if( mb->unsafeProp && !copystring(&t, "unsafe ", &len))
+               return base;
+       if( mb->sealedProp && !copystring(&t, "sealed ", &len))
+               return base;
+       if (!copystring(&t, operatorName(p->token), &len) ||
+               !copystring(&t, " ", &len) ||
+               !copystring(&t, getModuleId(p) ? getModuleId(p) : "user", &len) 
||
+               !copystring(&t, ".", &len) ||
+               !copystring(&t, getFunctionId(p), &len) ||
+               !copystring(&t, "(", &len))
+               return base;
 
        for (i = p->retc; i < p->argc; i++) {
                arg = renderTerm(mb, 0, p, i, (LIST_MAL_NAME | LIST_MAL_TYPE | 
LIST_MAL_PROPS));
-               if (arg) {
-                       snprintf(t, (len-(t-base)),"%s", arg);
+               if (arg && !copystring(&t, arg, &len)) {
                        GDKfree(arg);
+                       return base;
                }
-               advance(t,  base, len);
-               if( i<p->argc-1) {
-                       sprintf(t,", ");
-                       advance(t,base,len);
-               }
+               GDKfree(arg);
+               if( i<p->argc-1 && !copystring(&t, ", ", &len))
+                       return base;
        }
 
        advance(t,base,len);
-       if (p->varargs & VARARGS && t < base + len -3)
-               sprintf(t, "...");
-       advance(t,base,len);
+       if (p->varargs & VARARGS && !copystring(&t, "...", &len))
+               return base;
 
-       if (p->retc == 1 && t < base +len) {
-               *t++ = ')';
+       if (p->retc == 1) {
+               if (!copystring(&t, "):", &len))
+                       return base;
                tpe = getTypeName(getVarType(mb, getArg(p,0)));
-               snprintf(t,(len-(t-base)),":%s", tpe);
-               advance(t,base,len);
+               if (!copystring(&t, tpe, &len)) {
+                       GDKfree(tpe);
+                       return base;
+               }
                GDKfree(tpe);
-               if (p->varargs & VARRETS && t < base + len -3)
-                       sprintf(t, "...");
-               advance(t,base,len);
+               if (p->varargs & VARRETS && !copystring(&t, "...", &len))
+                       return base;
        } else {
-               if( t < base +len -3) sprintf(t, ") (");
-               t += 3;
+               if (!copystring(&t, ") (", &len))
+                       return base;
                for (i = 0; i < p->retc; i++) {
                        arg = renderTerm(mb, 0, p, i, (LIST_MAL_NAME | 
LIST_MAL_TYPE | LIST_MAL_PROPS));
-                       if (arg) {
-                               snprintf(t,(len-(t-base)),"%s", arg);
+                       if (arg && !copystring(&t, arg, &len)) {
                                GDKfree(arg);
+                               return base;
                        }
-                       advance(t,base,len);
-                       if( i<p->retc-1 && t < base + len) {
-                               sprintf(t,", ");
-                               advance(t,base,len);
-                       }
+                       GDKfree(arg);
+                       if( i<p->retc-1 && !copystring(&t, ", ", &len))
+                               return base;
                }
-               if (p->varargs & VARRETS && t < base +len -3)
-                       sprintf(t, "...");
-               advance(t,base,len);
-               if(t < base + len) *t++ = ')';
+               if (p->varargs & VARRETS && !copystring(&t, "...", &len))
+                       return base;
+               if (!copystring(&t, ")", &len))
+                       return base;
        }
 
-       if (mb->binding[0])
-               snprintf(t,(len-(t-base))," address %s;", mb->binding);
-       else
-               if( t <base + len) sprintf(t, ";");
-       return s;
+       if (mb->binding[0]) {
+               if (!copystring(&t, " address ", &len) ||
+                       !copystring(&t, mb->binding, &len))
+                       return base;
+       }
+       (void) copystring(&t, ";", &len);
+       return base;
 }
 
 str
@@ -248,53 +266,44 @@ operatorName(int i)
 str
 instruction2str(MalBlkPtr mb, MalStkPtr stk,  InstrPtr p, int flg)
 {
-       int i, tab = 4;
-       str base, s, t;
-       size_t len=  (mb->stop < 1000? 1000: mb->stop) * 128 /* max realistic 
line length estimate */;
+       int i;
+       str base, t;
+       size_t len = 512 + (p->argc * 128);              /* max realistic line 
length estimate */
        str arg;
 
-       base = s = GDKmalloc(len);
-       if ( s == NULL)
-               return s;
-       if (flg) {
-               s[0] = 0;
-               t = s;
-       } else {
-               s[0] = '#';
+       t = base = GDKmalloc(len);
+       if ( base == NULL)
+               return NULL;
+       if (!flg) {
+               *t++ = '#';
+               len--;
                if (p->typechk == TYPE_UNKNOWN) {
-                       s[1] = '!';     /* error */
-                       s[2] = 0;
-                       t = s + 2;
-               } else {
-                       s[1] = 0;
-                       t = s + 1;
+                       *t++ = '!';     /* error */
+                       len--;
                }
        }
-       advance(t,base,len);
+       *t = 0;
        if (p->token == REMsymbol && !( getModuleId(p) && 
strcmp(getModuleId(p),"querylog") == 0  && getFunctionId(p) && 
strcmp(getFunctionId(p),"define") == 0)) {
                /* do nothing */
        } else if (p->barrier) {
-               if (p->barrier == LEAVEsymbol || 
-                       p->barrier == REDOsymbol || 
-                       p->barrier == RETURNsymbol || 
-                       p->barrier == YIELDsymbol || 
+               if (p->barrier == LEAVEsymbol ||
+                       p->barrier == REDOsymbol ||
+                       p->barrier == RETURNsymbol ||
+                       p->barrier == YIELDsymbol ||
                        p->barrier == RAISEsymbol) {
-                       for(;tab>0;tab--) 
-                               *t++= ' ';
-                       *t= 0;
-                       advance(t,base,len);
+                       if (!copystring(&t, "    ", &len))
+                               return base;
                }
-               snprintf(t,(len-(t-base)), "%s ", operatorName(p->barrier));
-               advance(t,base,len);
-       } else
-       if( functionStart(p) && flg != LIST_MAL_CALL ){
-               return fcnDefinition(mb, p, s, flg, base, len);
+               arg = operatorName(p->barrier);
+               if (!copystring(&t, arg, &len) ||
+                       !copystring(&t, " ", &len))
+                       return base;
+       } else if( functionStart(p) && flg != LIST_MAL_CALL ){
+               return fcnDefinition(mb, p, t, flg, base, len + (t - base));
        } else if (!functionExit(p) && flg!=LIST_MAL_CALL) {
-                       // beautify with tabs
-               for(;tab>0;tab--) 
-                       *t++= ' ';
-               *t= 0;
-               advance(t,base,len);
+               // beautify with tabs
+               if (!copystring(&t, "    ", &len))
+                       return base;
        }
        switch (p->token<0?-p->token:p->token) {
        case FCNcall:
@@ -311,90 +320,99 @@ instruction2str(MalBlkPtr mb, MalStkPtr 
                        break;
 
                /* display multi-assignment list */
-               if (p->retc > 1)
-                       if( t< base+len) *t++ = '(';
+               if (p->retc > 1 && !copystring(&t, "(", &len))
+                       return base;
 
                for (i = 0; i < p->retc; i++) {
                        arg= renderTerm(mb, stk, p, i, flg);
                        if (arg) {
-                               snprintf(t,(len-(t-base)), "%s", arg);
+                               if (!copystring(&t, arg, &len)) {
+                                       GDKfree(arg);
+                                       return base;
+                               }
                                GDKfree(arg);
                        }
-                       advance(t,base,len);
-                       if ( t < base+len && i < p->retc - 1){
-                               *t++ = ',';
-                               *t++ = ' ';
-                       }
+                       if (i < p->retc - 1 && !copystring(&t, ", ", &len))
+                               return base;
                }
-               if (p->retc > 1)
-                       if( t< base+len) *t++ = ')';
+               if (p->retc > 1 && !copystring(&t, ")", &len))
+                       return base;
 
                if (p->argc > p->retc || getFunctionId(p)) {
-                       if( t< base+len-4) {
-                               sprintf(t, " := ");
-                               t += 4;
-                       }
+                       if (!copystring(&t, " := ", &len))
+                               return base;
                }
-               *t = 0;
                break;
        case ENDsymbol:
-               snprintf(t,(len-(t-base)), "end %s.%s", 
getModuleId(getInstrPtr(mb,0)), getFunctionId(getInstrPtr(mb, 0)));
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to