fix pgext uses a wrong field number, if the column has the same name as a resource or property column

Fri, 01 Nov 2024 12:25:52 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 01 Nov 2024 12:25:52 +0100
changeset 562
69fc4ecc5f60
parent 561
e1c92c126557
child 563
6ca97c99173e

fix pgext uses a wrong field number, if the column has the same name as a resource or property column

src/server/plugins/postgresql/webdav.c file | annotate | diff | comparison | revisions
--- a/src/server/plugins/postgresql/webdav.c	Fri Sep 20 20:30:57 2024 +0200
+++ b/src/server/plugins/postgresql/webdav.c	Fri Nov 01 12:25:52 2024 +0100
@@ -495,9 +495,11 @@
     }
     
     if(pg_create_propfind_query(rq, iscollection, ext, numext, &sql)) {
+        cxBufferDestroy(&sql);
         return 1;
     }
     query = sql.space;
+    log_ereport(LOG_DEBUG, "pg_dav_propfind_init query: %.*s\n", (int)sql.size, sql.space);
     
     // get all resources and properties
     size_t href_len = strlen(href);
@@ -521,10 +523,12 @@
             return 1;
         }
         if(cxBufferInit(&pname_buf, NULL, bufsize, a, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS)) {
+            cxBufferDestroy(&sql);
             cxBufferDestroy(&xmlns_buf);
             return 1;
         }
         if(pg_create_property_param_arrays(*outplist, &xmlns_buf, &pname_buf)) {
+            cxBufferDestroy(&sql);
             cxBufferDestroy(&xmlns_buf);
             cxBufferDestroy(&pname_buf);
             return 1;
@@ -549,6 +553,7 @@
             0);    // 0: result in text format
     int nrows = PQntuples(result);
     pool_free(rq->sn->pool, href_param);
+    cxBufferDestroy(&sql);
     if(buf_initialized) {
         cxBufferDestroy(&xmlns_buf);
         cxBufferDestroy(&pname_buf);
@@ -575,11 +580,34 @@
     pg->ext = ext;
     pg->numext = numext;
     if(ext) {
+        // build a map of all ext field names (excluding first fields from
+        // the resource and property table)
+        int nfields = PQnfields(result);
+        CxMap *fieldmap = cxHashMapCreate(pool_allocator(rq->sn->pool), sizeof(int), nfields);
+        if(!fieldmap) {
+            PQclear(result);
+            return 1;
+        }
+        // start with index 15 (see pg_dav_propfind_do for first column nums)
+        for(int i=15;i<nfields;i++) {
+            char *name = PQfname(result, i);
+            if(name) {
+                if(cxMapPut(fieldmap, name, &i)) {
+                    PQclear(result);
+                    return 1;
+                }
+            }
+        }
+        
         // get field_nums for all property extensions
         for(int i=0;i<numext;i++) {
             PgPropfindExtCol *c = &ext[i];
-            c->field_num = PQfnumber(result, c->ext->column);
+            //c->field_num = PQfnumber(result, c->ext->column);
+            int *fieldnum = cxMapGet(fieldmap, c->ext->column);
+            c->field_num = *fieldnum;
         }
+        
+        cxMapDestroy(fieldmap);
     }
     
     return 0;
@@ -617,7 +645,7 @@
         // 12: property lang
         // 13: property nsdeflist
         // 14: property value
-        
+            
         char *path = PQgetvalue(result, r, 0);
         char *res_id = PQgetvalue(result, r, 1);
         char *iscollection_str = PQgetvalue(result, r, 4);

mercurial