Fix multi-method query-style lookup quoters
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 1 Sep 2024 16:25:35 +0000 (17:25 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 1 Sep 2024 17:33:18 +0000 (18:33 +0100)
Broken-by: ac8aeb5485a8
12 files changed:
src/src/lookupapi.h
src/src/lookups/testdb.c
src/src/search.c
src/src/store.c
src/src/store.h
test/confs/3213
test/runtest
test/scripts/3200-testdb/3200
test/stderr/2610
test/stderr/2620
test/stderr/3200
test/stdout/3200

index af7bd51f6b95b1d6f3c98dac578d948bcc87fc66..524a2fc1dab80e5e2e3d0c8fac994b513fb73f2c 100644 (file)
@@ -7,6 +7,7 @@
 /* See the file NOTICE for conditions of use and distribution. */
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
 /* See the file NOTICE for conditions of use and distribution. */
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
+#define LOOKUPAPI_H
 
 /* The "type" field in each item is a set of bit flags:
 
 
 /* The "type" field in each item is a set of bit flags:
 
index 8de7090b7c3d990e6ea8da8ea18a9ef0f42ae144..2319291d501f14017a652d8e5196418ab28ff893 100644 (file)
@@ -61,6 +61,17 @@ return OK;
 }
 
 
 }
 
 
+/* Don't actually alter the string; just copy to quoted-pool memory */
+
+static uschar *
+testdb_quote(uschar * s, uschar * opt, unsigned idx)
+{
+int len = Ustrlen(s) + 1;
+uschar * quoted = store_get_quoted(len, s, idx, US"testdb");
+memcpy(quoted, s, len);
+return quoted;
+}
+
 /*************************************************
 *         Version reporting entry point          *
 *************************************************/
 /*************************************************
 *         Version reporting entry point          *
 *************************************************/
@@ -79,7 +90,7 @@ return g;
 }
 
 
 }
 
 
-static lookup_info _lookup_info = {
+static lookup_info testdb_lookup_info = {
   .name = US"testdb",                  /* lookup name */
   .type = lookup_querystyle,           /* query-style lookup */
   .open = testdb_open,                 /* open function */
   .name = US"testdb",                  /* lookup name */
   .type = lookup_querystyle,           /* query-style lookup */
   .open = testdb_open,                 /* open function */
@@ -87,7 +98,31 @@ static lookup_info _lookup_info = {
   .find = testdb_find,                 /* find function */
   .close = NULL,                       /* no close function */
   .tidy = NULL,                                /* no tidy function */
   .find = testdb_find,                 /* find function */
   .close = NULL,                       /* no close function */
   .tidy = NULL,                                /* no tidy function */
-  .quote = NULL,                       /* no quoting function */
+  .quote = testdb_quote,               /* quoting function */
+  .version_report = testdb_version_report          /* version reporting */
+};
+
+static lookup_info testdb2_lookup_info = {
+  .name = US"testdb2",                 /* lookup name */
+  .type = lookup_querystyle,           /* query-style lookup */
+  .open = testdb_open,                 /* open function */
+  .check = NULL,                       /* check function */
+  .find = testdb_find,                 /* find function */
+  .close = NULL,                       /* no close function */
+  .tidy = NULL,                                /* no tidy function */
+  .quote = testdb_quote,               /* same quoting function */
+  .version_report = testdb_version_report          /* version reporting */
+};
+
+static lookup_info testdb3_lookup_info = {
+  .name = US"testdb_nq",               /* lookup name */
+  .type = lookup_querystyle,           /* query-style lookup */
+  .open = testdb_open,                 /* open function */
+  .check = NULL,                       /* check function */
+  .find = testdb_find,                 /* find function */
+  .close = NULL,                       /* no close function */
+  .tidy = NULL,                                /* no tidy function */
+  .quote = NULL,                       /* NO quoting function */
   .version_report = testdb_version_report          /* version reporting */
 };
 
   .version_report = testdb_version_report          /* version reporting */
 };
 
@@ -95,7 +130,13 @@ static lookup_info _lookup_info = {
 #define testdb_lookup_module_info _lookup_module_info
 #endif
 
 #define testdb_lookup_module_info _lookup_module_info
 #endif
 
-static lookup_info *_lookup_list[] = { &_lookup_info };
-lookup_module_info testdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+static lookup_info *_lookup_list[] = {
+  &testdb_lookup_info,
+  &testdb2_lookup_info,
+  &testdb3_lookup_info
+};
+
+lookup_module_info testdb_lookup_module_info = {
+  LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 3 };
 
 /* End of lookups/testdb.c */
 
 /* End of lookups/testdb.c */
index ad55e878010d0ac2a7bdce3b9846937b391a00b0..981c1a73d362aa0cee450a14c663f69af8f4196a 100644 (file)
@@ -536,7 +536,6 @@ search_cache * c = (search_cache *)(t->data.ptr);
 const lookup_info * li = c->li;
 expiring_data * e = NULL;      /* compiler quietening */
 uschar * data = NULL;
 const lookup_info * li = c->li;
 expiring_data * e = NULL;      /* compiler quietening */
 uschar * data = NULL;
-int required_quoter_id = li->acq_num;
 int old_pool = store_pool;
 
 /* Lookups that return DEFER may not always set an error message. So that
 int old_pool = store_pool;
 
 /* Lookups that return DEFER may not always set an error message. So that
@@ -603,7 +602,7 @@ else
   */
 
   if (  !filename && li->quote
   */
 
   if (  !filename && li->quote
-     && is_tainted(keystring) && !is_quoted_like(keystring, required_quoter_id))
+     && is_tainted(keystring) && !is_quoted_like(keystring, li))
     {
     const uschar * ks = keystring;
     uschar * loc = acl_current_verb();
     {
     const uschar * ks = keystring;
     uschar * loc = acl_current_verb();
@@ -638,8 +637,8 @@ else
       const uschar * quoter_name;
       int q = quoter_for_address(ks, &quoter_name);
 
       const uschar * quoter_name;
       int q = quoter_for_address(ks, &quoter_name);
 
-      debug_printf_indent("required_quoter_id %d (%s) quoting %d (%s)\n",
-       required_quoter_id, li->name,
+      debug_printf_indent("required_quoter_id (%s) quoting %d (%s)\n",
+       li->name,
        q, quoter_name);
       }
 #endif
        q, quoter_name);
       }
 #endif
index 4824b5c54fc89a9dd43f9a2b02ca51a969d8f1eb..a609e5c61a5d3c035f10b18ead8919947d7d5a36 100644 (file)
@@ -659,20 +659,22 @@ found:
 There is extra complexity to handle lookup providers with multiple
 find variants but shared quote functions. */
 BOOL
 There is extra complexity to handle lookup providers with multiple
 find variants but shared quote functions. */
 BOOL
-is_quoted_like(const void * p, unsigned quoter)
+is_quoted_like(const void * p, const void * v_q_li)
 {
 {
-const uschar * p_name, * q_name = NULL;
-const lookup_info * p_li, * q_li;
+const uschar * p_name;
+const lookup_info * p_li, * q_li = v_q_li;
 void * p_qfn, * q_qfn;
 
 (void) quoter_for_address(p, &p_name);
 void * p_qfn, * q_qfn;
 
 (void) quoter_for_address(p, &p_name);
-(void) pool_for_quoter(quoter, &q_name);
 
 
-if (!p_name || !q_name) return FALSE;
+if (!p_name)
+  {
+  DEBUG(D_any) debug_printf("No quoter name for addr\n");
+  return FALSE;
+  }
 
 p_li = search_findtype(p_name, Ustrlen(p_name));
 p_qfn = p_li ? p_li->quote : NULL;
 
 p_li = search_findtype(p_name, Ustrlen(p_name));
 p_qfn = p_li ? p_li->quote : NULL;
-q_li = search_findtype(q_name, Ustrlen(q_name));
 q_qfn = q_li ? q_li->quote : NULL;
 
 BOOL y = p_qfn == q_qfn;
 q_qfn = q_li ? q_li->quote : NULL;
 
 BOOL y = p_qfn == q_qfn;
index f088647f16df314d181cfe30a3c55d832af88591..e54d45fc058c58e6746c97962cec38fc58cba5ad 100644 (file)
@@ -83,7 +83,7 @@ extern rmark   store_reset_3(rmark, const char *, int);
 #define GET_TAINTED    (const void *)1
 
 extern int     quoter_for_address(const void *, const uschar **);
 #define GET_TAINTED    (const void *)1
 
 extern int     quoter_for_address(const void *, const uschar **);
-extern BOOL    is_quoted_like(const void *, unsigned);
+extern BOOL    is_quoted_like(const void *, const void *);
 extern BOOL    is_real_quoter(int);
 extern void    debug_print_taint(const void * p);
 
 extern BOOL    is_real_quoter(int);
 extern void    debug_print_taint(const void * p);
 
index 5752f91edd7084a0c14330db77318b8bb339e916..77c0f34efaa12fb967c41508f0f136bf45507bd5 100644 (file)
@@ -14,7 +14,7 @@ acl_smtp_mail = check_mail
 begin ACL
 
 check_mail:
 begin ACL
 
 check_mail:
-  accept  senders = testdb;<$sender_address>
+  accept  senders = testdb;<${quote_testdb:$sender_address}>
 
 
 # End
 
 
 # End
index ae227810cbb24c07af5bbbdf1cab6a3e6a4006c9..70499312d368d23a810c4371b87c9381055f0517 100755 (executable)
@@ -1475,7 +1475,6 @@ RESET_AFTER_EXTRA_LINE_READ:
       }
 
     # Different builds will have different lookup types included
       }
 
     # Different builds will have different lookup types included
-    s/required_quoter_id \K\d+ \((\w+)\) quoting -1 \(NULL\)$/NN ($1) quoting -1 (NULL)/;
     # and different numbers of lookup types result in different type-code letters,
     # so convert them all to "0"
     s%(?<!lsearch)[^ ](?=TESTSUITE/aux-fixed/(?:0414.list[12]|0464.domains)$)%0%;
     # and different numbers of lookup types result in different type-code letters,
     # so convert them all to "0"
     s%(?<!lsearch)[^ ](?=TESTSUITE/aux-fixed/(?:0414.list[12]|0464.domains)$)%0%;
index f5b12972ddb874ec2f2e0d518a9e09caa9e8d8f5..6ea2c9865a62c85375eeeeffb651b046b6e19f87 100644 (file)
@@ -9,3 +9,15 @@ bad default:     ${lookup testdb*@{abcd}}
 bad default:     ${lookup testdb*{fail}}
 bad default:     ${lookup testdb*@{fail}}
 ****
 bad default:     ${lookup testdb*{fail}}
 bad default:     ${lookup testdb*@{fail}}
 ****
+#
+exim -be
+set,t acl_m0 = expected_fail
+set,t acl_m1 = barbaz
+set,t acl_m2 = foo_2
+set,t acl_m3 = foo_3
+missing quoter:  ${lookup testdb {$acl_m0}}
+proper quoter:   ${lookup testdb {${quote_testdb:$acl_m1}}}
+missing (but cached): ${lookup testdb {$acl_m1}}
+shared quoter:   ${lookup testdb2 {${quote_testdb:$acl_m2}}}
+quoter notreq:   ${lookup testdb_nq {$acl_m3}}
+****
index 564fb7b11257976f2bb094a14fa0ce263bea3457..f253cac9d002b52ffdc5747fbf15e3ca22ce0ae3 100644 (file)
@@ -377,9 +377,10 @@ close MYSQL connection: 127.0.0.1:PORT_N/test/root
 01:01:01 p1235     type=mysql key="select name from them where id = 'c'" opts="no_rd"
 01:01:01 p1235   cached data found but wrong opts;  database lookup required for select name from them where id = 'c'
 01:01:01 p1235                                (tainted)
 01:01:01 p1235     type=mysql key="select name from them where id = 'c'" opts="no_rd"
 01:01:01 p1235   cached data found but wrong opts;  database lookup required for select name from them where id = 'c'
 01:01:01 p1235                                (tainted)
+01:01:01 p1235  No quoter name for addr
 01:01:01 p1235  LOG: MAIN PANIC
 01:01:01 p1235    tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 26): select name from them where id = 'c'
 01:01:01 p1235  LOG: MAIN PANIC
 01:01:01 p1235    tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 26): select name from them where id = 'c'
-01:01:01 p1235   required_quoter_id NN (mysql) quoting -1 (NULL)
+01:01:01 p1235   required_quoter_id (mysql) quoting -1 (NULL)
 01:01:01 p1235   MySQL query: "select name from them where id = 'c'" opts 'no_rd'
 01:01:01 p1235   MYSQL using cached connection for 127.0.0.1:PORT_N/test/root
 01:01:01 p1235   MYSQL: no data found
 01:01:01 p1235   MySQL query: "select name from them where id = 'c'" opts 'no_rd'
 01:01:01 p1235   MYSQL using cached connection for 127.0.0.1:PORT_N/test/root
 01:01:01 p1235   MYSQL: no data found
@@ -536,9 +537,10 @@ close MYSQL connection: 127.0.0.1:PORT_N/test/root
 01:01:01 p1235     type=mysql key="servers=127.0.0.1::PORT_N; select name from them where id = 'c'" opts=NULL
 01:01:01 p1235   database lookup required for servers=127.0.0.1::PORT_N; select name from them where id = 'c'
 01:01:01 p1235                                (tainted)
 01:01:01 p1235     type=mysql key="servers=127.0.0.1::PORT_N; select name from them where id = 'c'" opts=NULL
 01:01:01 p1235   database lookup required for servers=127.0.0.1::PORT_N; select name from them where id = 'c'
 01:01:01 p1235                                (tainted)
+01:01:01 p1235  No quoter name for addr
 01:01:01 p1235  LOG: MAIN PANIC
 01:01:01 p1235    tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 39): select name from them where id = 'c'
 01:01:01 p1235  LOG: MAIN PANIC
 01:01:01 p1235    tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 39): select name from them where id = 'c'
-01:01:01 p1235   required_quoter_id NN (mysql) quoting -1 (NULL)
+01:01:01 p1235   required_quoter_id (mysql) quoting -1 (NULL)
 01:01:01 p1235   MySQL query: "servers=127.0.0.1::PORT_N; select name from them where id = 'c'" opts 'NULL'
 01:01:01 p1235  LOG: MAIN
 01:01:01 p1235    Exim configuration error in line 89 of TESTSUITE/test-config:
 01:01:01 p1235   MySQL query: "servers=127.0.0.1::PORT_N; select name from them where id = 'c'" opts 'NULL'
 01:01:01 p1235  LOG: MAIN
 01:01:01 p1235    Exim configuration error in line 89 of TESTSUITE/test-config:
@@ -842,9 +844,10 @@ processing address_data
    type=mysql key="select name from them where id='ph10' limit 1" opts=NULL
  database lookup required for select name from them where id='ph10' limit 1
                               (tainted)
    type=mysql key="select name from them where id='ph10' limit 1" opts=NULL
  database lookup required for select name from them where id='ph10' limit 1
                               (tainted)
+No quoter name for addr
 LOG: MAIN PANIC
   tainted search query is not properly quoted (router r1, TESTSUITE/test-config 68): select name from them where id='ph10' limit 1
 LOG: MAIN PANIC
   tainted search query is not properly quoted (router r1, TESTSUITE/test-config 68): select name from them where id='ph10' limit 1
- required_quoter_id NN (mysql) quoting -1 (NULL)
+ required_quoter_id (mysql) quoting -1 (NULL)
  MySQL query: "select name from them where id='ph10' limit 1" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:PORT_N/test/root
  creating new cache entry
  MySQL query: "select name from them where id='ph10' limit 1" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:PORT_N/test/root
  creating new cache entry
@@ -886,9 +889,10 @@ appendfile transport entered
    type=mysql key="select id from them where id='ph10'" opts=NULL
  database lookup required for select id from them where id='ph10'
                               (tainted)
    type=mysql key="select id from them where id='ph10'" opts=NULL
  database lookup required for select id from them where id='ph10'
                               (tainted)
+No quoter name for addr
 LOG: MAIN
   tainted search query is not properly quoted (transport t1, TESTSUITE/test-config 82): select id from them where id='ph10'
 LOG: MAIN
   tainted search query is not properly quoted (transport t1, TESTSUITE/test-config 82): select id from them where id='ph10'
- required_quoter_id NN (mysql) quoting -1 (NULL)
+ required_quoter_id (mysql) quoting -1 (NULL)
  MySQL query: "select id from them where id='ph10'" opts 'NULL'
  MYSQL new connection: host=127.0.0.1 port=PORT_N socket=NULL database=test user=root
  creating new cache entry
  MySQL query: "select id from them where id='ph10'" opts 'NULL'
  MYSQL new connection: host=127.0.0.1 port=PORT_N socket=NULL database=test user=root
  creating new cache entry
index 0d42feccbb9365f2106f08e5b8eac0243760f789..3904277905a101c3103ab8e7c7e543755f1c79e4 100644 (file)
@@ -293,9 +293,10 @@ check set acl_m0 = ok:   ${lookup pgsql                    {select name from the
    type=pgsql key="select name from them where id = 'c'" opts=NULL
  cached data found but no_rd option set;  database lookup required for select name from them where id = 'c'
                               (tainted)
    type=pgsql key="select name from them where id = 'c'" opts=NULL
  cached data found but no_rd option set;  database lookup required for select name from them where id = 'c'
                               (tainted)
+No quoter name for addr
 LOG: MAIN PANIC
   tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 27): select name from them where id = 'c'
 LOG: MAIN PANIC
   tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 27): select name from them where id = 'c'
- required_quoter_id NN (pgsql) quoting -1 (NULL)
+ required_quoter_id (pgsql) quoting -1 (NULL)
  PostgreSQL query: "select name from them where id = 'c'" opts 'NULL'
  PGSQL using cached connection for localhost:PORT_N/test/CALLER
  PGSQL: no data found
  PostgreSQL query: "select name from them where id = 'c'" opts 'NULL'
  PGSQL using cached connection for localhost:PORT_N/test/CALLER
  PGSQL: no data found
@@ -488,9 +489,10 @@ check set acl_m0 = ok:   ${lookup pgsql                    {select name from the
    type=pgsql key="select name from them where id = 'c'" opts=NULL
  cached data found but no_rd option set;  database lookup required for select name from them where id = 'c'
                               (tainted)
    type=pgsql key="select name from them where id = 'c'" opts=NULL
  cached data found but no_rd option set;  database lookup required for select name from them where id = 'c'
                               (tainted)
+No quoter name for addr
 LOG: MAIN PANIC
   tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 27): select name from them where id = 'c'
 LOG: MAIN PANIC
   tainted search query is not properly quoted (ACL warn, TESTSUITE/test-config 27): select name from them where id = 'c'
- required_quoter_id NN (pgsql) quoting -1 (NULL)
+ required_quoter_id (pgsql) quoting -1 (NULL)
  PostgreSQL query: "select name from them where id = 'c'" opts 'NULL'
  PGSQL using cached connection for localhost:PORT_N/test/CALLER
  PGSQL: no data found
  PostgreSQL query: "select name from them where id = 'c'" opts 'NULL'
  PGSQL using cached connection for localhost:PORT_N/test/CALLER
  PGSQL: no data found
index 2f416adf51c3caf964d2603416ae1ef363ee4523..aaff83d719baad22feddba15f3378c8d390a66b7 100644 (file)
@@ -1 +1,2 @@
 1999-03-02 09:44:33 defaults using "*" or "*@" are not permitted for lookup type "testdb*"
 1999-03-02 09:44:33 defaults using "*" or "*@" are not permitted for lookup type "testdb*"
+1999-03-02 09:44:33 tainted search query is not properly quoted: expected_fail
index 04ff51884dc33f3cbe95676a375f127b128feec5..4ad32483586d9b644cbf5c4c47ba43d525c6054b 100644 (file)
@@ -1,3 +1,12 @@
 > match_ip:        12 true
 > match_ip:        13 
 > match_ip:        12 true
 > match_ip:        13 
-> 
\ No newline at end of file
+> > variable m0 set
+> variable m1 set
+> variable m2 set
+> variable m3 set
+> missing quoter:  expected_fail
+> proper quoter:   barbaz
+> missing (but cached): barbaz
+> shared quoter:   foo_2
+> quoter notreq:   foo_3
+>