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