Changeset: 9832790b17a3 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9832790b17a3
Modified Files:
        monetdb5/extras/rapi/rapi.c
Branch: Dec2016
Log Message:

Dynamically allocate space for R command in rapi.eval.
This fixes bug 4034.


diffs (116 lines):

diff --git a/monetdb5/extras/rapi/rapi.c b/monetdb5/extras/rapi/rapi.c
--- a/monetdb5/extras/rapi/rapi.c
+++ b/monetdb5/extras/rapi/rapi.c
@@ -238,9 +238,10 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
        ParseStatus status;
        int i = 0;
        char argbuf[64];
-       char argnames[10000] = "";
+       char *argnames = NULL;
+       size_t argnameslen;
        size_t pos;
-       char* rcall;
+       char* rcall = NULL;
        size_t rcalllen;
        int ret_cols = 0; /* int because pci->retc is int, too*/
        str *args;
@@ -265,15 +266,8 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                sqlfun = *(sql_func**) getArgReference(stk, pci, pci->retc);
        }
 
-       rcalllen = strlen(exprStr) + sizeof(argnames) + 100;
-       rcall = malloc(rcalllen);
-       if (rcall == NULL) {
-               throw(MAL, "rapi.eval", MAL_MALLOC_FAIL);
-       }
-
        args = (str*) GDKzalloc(sizeof(str) * pci->argc);
        if (args == NULL) {
-               free(rcall);
                throw(MAL, "rapi.eval", MAL_MALLOC_FAIL);
        }
 
@@ -297,6 +291,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                }
        }
        // the first unknown argument is the group, we don't really care for 
the rest.
+       argnameslen = 2;
        for (i = pci->retc + 2; i < pci->argc; i++) {
                if (args[i] == NULL) {
                        if (!seengrp && grouped) {
@@ -307,6 +302,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                                args[i] = GDKstrdup(argbuf);
                        }
                }
+               argnameslen += strlen(args[i]) + 2; /* extra for ", " */
        }
 
        // install the MAL variables into the R environment
@@ -360,20 +356,27 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
         * this is also compatible with PL/R
         */
        pos = 0;
-       for (i = pci->retc + 2; i < pci->argc && pos < sizeof(argnames); i++) {
-               pos += snprintf(argnames + pos, sizeof(argnames) - pos, "%s%s",
+       argnames = malloc(argnameslen);
+       if (argnames == NULL) {
+               msg = createException(MAL, "rapi.eval", MAL_MALLOC_FAIL);
+               goto wrapup;
+       }
+       argnames[0] = '\0';
+       for (i = pci->retc + 2; i < pci->argc; i++) {
+               pos += snprintf(argnames + pos, argnameslen - pos, "%s%s",
                                                args[i], i < pci->argc - 1 ? ", 
" : "");
        }
-       if (pos >= sizeof(argnames)) {
-               msg = createException(MAL, "rapi.eval", "Command too large");
+       rcalllen = 2 * pos + strlen(exprStr) + 100;
+       rcall = malloc(rcalllen);
+       if (rcall == NULL) {
+               msg = createException(MAL, "rapi.eval", MAL_MALLOC_FAIL);
                goto wrapup;
        }
-       if (snprintf(rcall, rcalllen,
-                                "ret <- as.data.frame((function(%s){%s})(%s), 
nm=NA, stringsAsFactors=F)\n",
-                                argnames, exprStr, argnames) >= (int) 
rcalllen) {
-               msg = createException(MAL, "rapi.eval", "Command too large");
-               goto wrapup;
-       }
+       snprintf(rcall, rcalllen,
+                        "ret <- as.data.frame((function(%s){%s})(%s), nm=NA, 
stringsAsFactors=F)\n",
+                        argnames, exprStr, argnames);
+       free(argnames);
+       argnames = NULL;
 #ifdef _RAPI_DEBUG_
        printf("# R call %s\n",rcall);
 #endif
@@ -421,7 +424,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                if (bat_type == TYPE_any || bat_type == TYPE_void) {
                        getArgType(mb,pci,i) = bat_type;
                        msg = createException(MAL, "rapi.eval",
-                                                                         
"Unknown return value, possibly projecting with no parameters.");
+                                                                 "Unknown 
return value, possibly projecting with no parameters.");
                        goto wrapup;
                }
 
@@ -429,7 +432,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                b = sexp_to_bat(ret_col, bat_type);
                if (b == NULL) {
                        msg = createException(MAL, "rapi.eval",
-                                                                               
                  "Failed to convert column %i", i);
+                                                                 "Failed to 
convert column %i", i);
                        goto wrapup;
                }
                // bat return
@@ -449,7 +452,10 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
        UNPROTECT(1);
   wrapup:
        MT_lock_unset(&rapiLock);
-       free(rcall);
+       if (argnames)
+               free(argnames);
+       if (rcall)
+               free(rcall);
        for (i = 0; i < pci->argc; i++)
                GDKfree(args[i]);
        GDKfree(args);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to