Changeset: 09dad7e2d985 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=09dad7e2d985
Added Files:
        
sql/test/BugTracker-2015/Tests/crash_timestamp_convert.Bug-3816.stable.out.Darwin.src
        
sql/test/BugTracker-2015/Tests/crash_timestamp_convert.Bug-3816.stable.out.FreeBSD
        sql/test/BugTracker-2017/Tests/fullouterjoinfilter.Bug-6256.sql
        sql/test/BugTracker-2017/Tests/fullouterjoinfilter.Bug-6256.stable.err
        sql/test/BugTracker-2017/Tests/fullouterjoinfilter.Bug-6256.stable.out
        sql/test/BugTracker-2017/Tests/wrong_aggregation_count.Bug-6257.sql
        
sql/test/BugTracker-2017/Tests/wrong_aggregation_count.Bug-6257.stable.err
        
sql/test/BugTracker-2017/Tests/wrong_aggregation_count.Bug-6257.stable.out
Modified Files:
        sql/backends/monet5/sql_execute.c
        sql/backends/monet5/sql_scenario.h
        sql/backends/monet5/vaults/fits/fits.c
        sql/backends/monet5/vaults/netcdf/netcdf.c
        sql/test/BugTracker-2015/Tests/schema-trigger.Bug-3710.sql
        sql/test/BugTracker-2015/Tests/schema-trigger.Bug-3710.stable.err
        sql/test/BugTracker-2015/Tests/schema-trigger.Bug-3710.stable.out
        sql/test/BugTracker-2016/Tests/convert-function-test.Bug-3460.stable.out
        
sql/test/BugTracker-2016/Tests/convert-function-test.Bug-3460.stable.out.int128
        sql/test/BugTracker-2017/Tests/All
        
sql/test/BugTracker-2017/Tests/crash_correlated_subqueries_in_select.Bug-6254.sql
        
sql/test/BugTracker-2017/Tests/crash_correlated_subqueries_in_select.Bug-6254.stable.out
Branch: default
Log Message:

Merge with Dec2016 branch.


diffs (truncated from 1195 to 300 lines):

diff --git a/sql/backends/monet5/sql_execute.c 
b/sql/backends/monet5/sql_execute.c
--- a/sql/backends/monet5/sql_execute.c
+++ b/sql/backends/monet5/sql_execute.c
@@ -352,6 +352,49 @@ SQLrun(Client c, backend *be, mvc *m){
        return msg;
 }
 
+/*
+ * Escape single quotes and backslashes. This is important to do before calling
+ * SQLstatementIntern, if we are pasting user provided strings into queries
+ * passed to the SQLstatementIntern. Otherwise we open ourselves to SQL
+ * injection attacks.
+ *
+ * It returns the input string with all the single quotes(') and the 
backslashes
+ * (\) doubled, or NULL, if it could not allocate enough space.
+ *
+ * The caller is responsible to free the returned value.
+ */
+str
+SQLescapeString(str s)
+{
+       str ret = NULL;
+       char *p, *q;
+       int len = 0;
+
+       if(!s) {
+               return NULL;
+       }
+
+       /* At most we will need 2*strlen(s) + 1 characters */
+       len = strlen(s);
+       ret = (str)GDKmalloc(2*len + 1);
+       if (!ret) {
+               return NULL;
+       }
+
+       for (p = s, q = ret; *p != '\0'; p++, q++) {
+               *q = *p;
+               if (*p == '\'') {
+                       *(++q) = '\'';
+               }
+               else if (*p == '\\') {
+                       *(++q) = '\\';
+               }
+       }
+
+       *q = '\0';
+       return ret;
+}
+
 str
 SQLstatementIntern(Client c, str *expr, str nme, bit execute, bit output, 
res_table **result)
 {
diff --git a/sql/backends/monet5/sql_scenario.h 
b/sql/backends/monet5/sql_scenario.h
--- a/sql/backends/monet5/sql_scenario.h
+++ b/sql/backends/monet5/sql_scenario.h
@@ -43,6 +43,7 @@ sql5_export str SQLstatementIntern(Clien
 sql5_export str SQLcompile(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 sql5_export str SQLinclude(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 sql5_export str SQLCacheRemove(Client c, str nme);
+sql5_export str SQLescapeString(str s);
 
 sql5_export MT_Lock sql_contextLock;
 #endif /* _SQL_SCENARIO_H_ */
diff --git a/sql/backends/monet5/vaults/fits/fits.c 
b/sql/backends/monet5/vaults/fits/fits.c
--- a/sql/backends/monet5/vaults/fits/fits.c
+++ b/sql/backends/monet5/vaults/fits/fits.c
@@ -31,8 +31,6 @@
 
 #define FITS_INS_COL "INSERT INTO sys.fits_columns(id, name, type, units, 
number, table_id) \
         VALUES(%d,'%s','%s','%s',%d,%d);"
-#define FILE_INS "INSERT INTO sys.fits_files(id, name) VALUES (%d, '%s');"
-#define DEL_TABLE "DELETE FROM sys.fitsfiles;"
 #define ATTACHDIR "call sys.fitsattach('%s');"
 
 static void
@@ -572,14 +570,25 @@ str FITSdir(Client cntxt, MalBlkPtr mb, 
                s = stmt;
 
                while ((ep = readdir(dp)) != NULL && !msg) {
-                       snprintf(fname, BUFSIZ, "%s%s", dir, ep->d_name);
+                       char *filename = SQLescapeString(ep->d_name);
+                       if (!filename) {
+                               msg = createException(MAL, "fits.listdir", 
MAL_MALLOC_FAIL);
+                               break;
+                       }
+
+                       snprintf(fname, BUFSIZ, "%s%s", dir, filename);
                        status = 0;
                        fits_open_file(&fptr, fname, READONLY, &status);
                        if (status == 0) {
                                snprintf(stmt, BUFSIZ, ATTACHDIR, fname);
+#ifndef NDEBUG
+                               fprintf(stderr, "Executing:\n%s\n", s);
+#endif
                                msg = SQLstatementIntern(cntxt, &s, 
"fits.listofdir", TRUE, FALSE, NULL);
                                fits_close_file(fptr, &status);
                        }
+
+                       GDKfree(filename);
                }
                (void)closedir(dp);
        } else
@@ -593,6 +602,7 @@ str FITSdirpat(Client cntxt, MalBlkPtr m
        str msg = MAL_SUCCEED;
        str dir = *getArgReference_str(stk, pci, 1);
        str pat = *getArgReference_str(stk, pci, 2);
+       char *filename = NULL;
        fitsfile *fptr;
        char *s;
        int status = 0;
@@ -601,6 +611,7 @@ str FITSdirpat(Client cntxt, MalBlkPtr m
        size_t j = 0;
 
        (void)mb;
+
        globbuf.gl_offs = 0;
        snprintf(fulldirectory, BUFSIZ, "%s%s", dir, pat);
        glob(fulldirectory, GLOB_DOOFFS, NULL, &globbuf);
@@ -608,7 +619,7 @@ str FITSdirpat(Client cntxt, MalBlkPtr m
        /*      fprintf(stderr,"#fulldir: %s \nSize: %lu\n",fulldirectory, 
globbuf.gl_pathc);*/
 
        if (globbuf.gl_pathc == 0)
-               throw(MAL, "listdir", "Couldn't open the directory or there are 
no files that match the pattern");
+               throw(MAL, "fits.listdirpat", "Couldn't open the directory or 
there are no files that match the pattern");
 
        for (j = 0; j < globbuf.gl_pathc; j++) {
                char stmt[BUFSIZ];
@@ -616,12 +627,21 @@ str FITSdirpat(Client cntxt, MalBlkPtr m
 
                s = stmt;
                snprintf(fname, BUFSIZ, "%s", globbuf.gl_pathv[j]);
+               filename = SQLescapeString(fname);
+               if (!filename) {
+                       throw(MAL, "fits.listdirpat", MAL_MALLOC_FAIL);
+               }
                status = 0;
-               fits_open_file(&fptr, fname, READONLY, &status);
+               fits_open_file(&fptr, filename, READONLY, &status);
                if (status == 0) {
-                       snprintf(stmt, BUFSIZ, ATTACHDIR, fname);
+                       snprintf(stmt, BUFSIZ, ATTACHDIR, filename);
+                       GDKfree(filename);
+#ifndef NDEBUG
+                       fprintf(stderr, "Executing:\n%s\n", s);
+#endif
                        msg = SQLstatementIntern(cntxt, &s, 
"fits.listofdirpat", TRUE, FALSE, NULL);
                        fits_close_file(fptr, &status);
+
                        break;
                }
        }
@@ -664,6 +684,7 @@ str FITSattach(Client cntxt, MalBlkPtr m
        char tname[BUFSIZ], *tname_low = NULL, *s, bname[BUFSIZ], stmt[BUFSIZ];
        long tbcol; /* type long used by fits library */
        char cname[BUFSIZ], tform[BUFSIZ], tunit[BUFSIZ], tnull[BUFSIZ], 
tdisp[BUFSIZ];
+       char *esc_cname, *esc_tform, *esc_tunit;
        double tscal, tzero;
        char xtensionname[BUFSIZ] = "", stilversion[BUFSIZ] = "";
        char stilclass[BUFSIZ] = "", tdate[BUFSIZ] = "", orig[BUFSIZ] = "", 
comm[BUFSIZ] = "";
@@ -807,7 +828,26 @@ str FITSattach(Client cntxt, MalBlkPtr m
                cid = store_funcs.count_col(tr, col, 1) + 1;
                for (j = 1; j <= cnum; j++, cid++) {
                        fits_get_acolparms(fptr, j, cname, &tbcol, tunit, 
tform, &tscal, &tzero, tnull, tdisp, &status);
-                       snprintf(stmt, BUFSIZ, FITS_INS_COL, (int)cid, cname, 
tform, tunit, j, (int)tid);
+                       /* escape the various strings to avoid SQL injection 
attacks */
+                       esc_cname = SQLescapeString(cname);
+                       if (!esc_cname) {
+                               throw(MAL, "fits.attach", MAL_MALLOC_FAIL);
+                       }
+                       esc_tform = SQLescapeString(tform);
+                       if (!esc_tform) {
+                               GDKfree(esc_cname);
+                               throw(MAL, "fits.attach", MAL_MALLOC_FAIL);
+                       }
+                       esc_tunit = SQLescapeString(tunit);
+                       if (!esc_tform) {
+                               GDKfree(esc_tform);
+                               GDKfree(esc_cname);
+                               throw(MAL, "fits.attach", MAL_MALLOC_FAIL);
+                       }
+                       snprintf(stmt, BUFSIZ, FITS_INS_COL, (int)cid, 
esc_cname, esc_tform, esc_tunit, j, (int)tid);
+                       GDKfree(esc_tunit);
+                       GDKfree(esc_tform);
+                       GDKfree(esc_cname);
                        msg = SQLstatementIntern(cntxt, &s, "fits.attach", 
TRUE, FALSE, NULL);
                        if (msg != MAL_SUCCEED) {
                                fits_close_file(fptr, &status);
diff --git a/sql/backends/monet5/vaults/netcdf/netcdf.c 
b/sql/backends/monet5/vaults/netcdf/netcdf.c
--- a/sql/backends/monet5/vaults/netcdf/netcdf.c
+++ b/sql/backends/monet5/vaults/netcdf/netcdf.c
@@ -232,13 +232,14 @@ NCDFattach(Client cntxt, MalBlkPtr mb, M
 
        size_t dlen, alen;
        char dname[NC_MAX_NAME+1], vname[NC_MAX_NAME+1], aname[NC_MAX_NAME +1], 
-         abuf[80], *aval;
+               abuf[80], *aval;
        char **dims = NULL;
        nc_type vtype, atype; /* == int */
 
        int retval, avalint;
        float avalfl;
        double avaldbl;
+       str esc_str0, esc_str1;
 
        msg = getSQLContext(cntxt, mb, &m, NULL);
        if (msg)
@@ -278,21 +279,34 @@ header: %s", nc_strerror(retval));
        col = mvc_bind_column(m, tfiles, "file_id");
        fid = store_funcs.count_col(tr, col, 1) + 1;
 
-       snprintf(buf, BUFSIZ, INSFILE, (int)fid, fname);
+       esc_str0 = SQLescapeString(fname);
+       if (!esc_str0) {
+               msg = createException(MAL, "netcdf.attach", MAL_MALLOC_FAIL);
+               goto finish;
+       }
+       snprintf(buf, BUFSIZ, INSFILE, (int)fid, esc_str0);
+       GDKfree(esc_str0);
        if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, 
FALSE, NULL))
-               != MAL_SUCCEED )
+                != MAL_SUCCEED )
            goto finish;
 
        /* Read dimensions from NetCDF header and insert a row for each one 
into netcdf_dims table */
 
        dims = (char **)GDKzalloc(sizeof(char *) * ndims);
        for (didx = 0; didx < ndims; didx++){
-           if ((retval = nc_inq_dim(ncid, didx, dname, &dlen)))
+               if ((retval = nc_inq_dim(ncid, didx, dname, &dlen)) != 0)
                return createException(MAL, "netcdf.attach", "Cannot read 
dimension %d : %s", didx, nc_strerror(retval));
 
-           snprintf(buf, BUFSIZ, INSDIM, didx, (int)fid, dname, (int)dlen);
+               esc_str0 = SQLescapeString(dname);
+               if (!esc_str0) {
+                       msg = createException(MAL, "netcdf.attach", 
MAL_MALLOC_FAIL);
+                       goto finish;
+               }
+
+               snprintf(buf, BUFSIZ, INSDIM, didx, (int)fid, esc_str0, 
(int)dlen);
+               GDKfree(esc_str0);
            if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, 
FALSE, NULL))
-        != MAL_SUCCEED )
+                        != MAL_SUCCEED )
                goto finish;
 
            dims[didx] = GDKstrdup(dname);
@@ -302,24 +316,31 @@ header: %s", nc_strerror(retval));
        for (vidx = 0; vidx < nvars; vidx++){
            if ( (retval = nc_inq_var(ncid, vidx, vname, &vtype, &vndims, 
vdims, &vnatts)))
                return createException(MAL, "netcdf.attach", 
-                            "Cannot read variable %d : %s", 
-                            vidx, nc_strerror(retval));
+                                                                  "Cannot read 
variable %d : %s",
+                                                                  vidx, 
nc_strerror(retval));
 
        /* Check if this is coordinate variable */
         if ( (vndims == 1) && ( strcmp(vname, dims[vdims[0]]) == 0 ))
                coord_dim_id = vdims[0];
         else coord_dim_id = -1;
 
-           snprintf(buf, BUFSIZ, INSVAR, vidx, (int)fid, vname, 
prim_type_name(vtype), vndims, coord_dim_id);
+               esc_str0 = SQLescapeString(vname);
+               if (!esc_str0) {
+                       msg = createException(MAL, "netcdf.attach", 
MAL_MALLOC_FAIL);
+                       goto finish;
+               }
+
+               snprintf(buf, BUFSIZ, INSVAR, vidx, (int)fid, esc_str0, 
prim_type_name(vtype), vndims, coord_dim_id);
+               GDKfree(esc_str0);
            if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, 
FALSE, NULL))
-               != MAL_SUCCEED )
+                        != MAL_SUCCEED )
             goto finish;
 
            if ( coord_dim_id < 0 ){
                for (i = 0; i < vndims; i++){
                 snprintf(buf, BUFSIZ, INSVARDIM, vidx, vdims[i], (int)fid, i);
                 if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", 
TRUE, FALSE, NULL))
-                  != MAL_SUCCEED )
+                                        != MAL_SUCCEED )
                        goto finish;
                }
            }
@@ -329,62 +350,74 @@ header: %s", nc_strerror(retval));
             for (aidx = 0; aidx < vnatts; aidx++){
                 if ((retval = nc_inq_attname(ncid,vidx,aidx,aname)))
                     return createException(MAL, "netcdf.attach",
-                        "Cannot read attribute %d of variable %d: %s",
-                        aidx, vidx, nc_strerror(retval));
+                                                                               
   "Cannot read attribute %d of variable %d: %s",
+                                                                               
   aidx, vidx, nc_strerror(retval));
 
-               if ((retval = nc_inq_att(ncid,vidx,aname,&atype,&alen)))
+                               if ((retval = 
nc_inq_att(ncid,vidx,aname,&atype,&alen)))
                     return createException(MAL, "netcdf.attach",
-                           "Cannot read attribute %s type and length: %s",
-                           aname, nc_strerror(retval));
+                                                                               
   "Cannot read attribute %s type and length: %s",
+                                                                               
   aname, nc_strerror(retval));
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to