diff -u sm.orig/mod_disco_publish.c sm/mod_disco_publish.c --- sm.orig/mod_disco_publish.c Sat Nov 6 09:03:14 2004 +++ sm/mod_disco_publish.c Sat Nov 6 09:50:31 2004 @@ -141,10 +141,10 @@ /* make a filter */ if(di->node[0] == '\0') /* filter is (jid=blah) */ - sprintf(filter, "(jid=%s)", jid_full(di->jid)); + sprintf(filter, "(jid=%i:%s)", strlen(jid_full(di->jid)), jid_full(di->jid)); else /* filter is (&(jid=blah)(node=moreblah)) */ - sprintf(filter, "(&(jid=%s)(node=%s))", jid_full(di->jid), di->node); + sprintf(filter, "(&(jid=%i:%s)(node=%i:%s))", strlen(jid_full(di->jid)), jid_full(di->jid), strlen(di->node), di->node); /* sucks if it fails, but we can't do anything about it anyway */ storage_delete(mod->mm->sm->st, "disco-items", jid_user(user->jid), filter); @@ -199,10 +199,10 @@ /* make a filter */ if(di->node[0] == '\0') /* filter is (jid=blah) */ - sprintf(filter, "(jid=%s)", jid_full(di->jid)); + sprintf(filter, "(jid=%i:%s)", strlen(jid_full(di->jid)), jid_full(di->jid)); else /* filter is (&(jid=blah)(node=moreblah)) */ - sprintf(filter, "(&(jid=%s)(node=%s))", jid_full(di->jid), di->node); + sprintf(filter, "(&(jid=%i:%s)(node=%i:%s))", strlen(jid_full(di->jid)), jid_full(di->jid), strlen(di->node), di->node); /* prepare objects */ os = os_new(); diff -u sm.orig/mod_iq_private.c sm/mod_iq_private.c --- sm.orig/mod_iq_private.c Sat Nov 6 09:03:14 2004 +++ sm/mod_iq_private.c Sat Nov 6 09:57:54 2004 @@ -76,7 +76,7 @@ /* get */ if(pkt->type == pkt_IQ) { - snprintf(filter, 4096, "(ns=%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); + snprintf(filter, 4096, "(ns=%i:%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); ret = storage_get(sess->user->sm->st, "private", jid_user(sess->jid), filter, &os); switch(ret) { case st_SUCCESS: @@ -135,7 +135,7 @@ os_object_put(o, "ns", filter, os_type_STRING); os_object_put(o, "xml", pkt->nad, os_type_NAD); - snprintf(filter, 4096, "(ns=%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); + snprintf(filter, 4096, "(ns=%i:%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); ret = storage_replace(sess->user->sm->st, "private", jid_user(sess->jid), filter, os); os_free(os); diff -u sm.orig/mod_privacy.c sm/mod_privacy.c --- sm.orig/mod_privacy.c Sat Nov 6 09:03:14 2004 +++ sm/mod_privacy.c Sat Nov 6 09:54:16 2004 @@ -804,7 +804,7 @@ } /* write the whole list out */ - sprintf(filter, "(list=%s)", zlist->name); + sprintf(filter, "(list=%i:%s)", strlen(zlist->name), zlist->name); ret = storage_replace(mod->mm->sm->st, "privacy-items", jid_user(sess->user->jid), filter, os); os_free(os); diff -u sm.orig/mod_roster.c sm/mod_roster.c --- sm.orig/mod_roster.c Sat Nov 6 09:03:14 2004 +++ sm/mod_roster.c Sat Nov 6 10:04:34 2004 @@ -79,13 +79,13 @@ os_object_put(o, "from", &item->from, os_type_BOOLEAN); os_object_put(o, "ask", &item->ask, os_type_INTEGER); - snprintf(filter, 4096, "(jid=%s)", jid_full(item->jid)); + snprintf(filter, 4096, "(jid=%i:%s)", strlen(jid_full(item->jid)), jid_full(item->jid)); storage_replace(user->sm->st, "roster-items", jid_user(user->jid), filter, os); os_free(os); - snprintf(filter, 4096, "(jid=%s)", jid_full(item->jid)); + snprintf(filter, 4096, "(jid=%i:%s)", strlen(jid_full(item->jid)), jid_full(item->jid)); if(item->ngroups == 0) { storage_delete(user->sm->st, "roster-groups", jid_user(user->jid), filter); @@ -294,10 +294,10 @@ xhash_zap(sess->user->roster, jid_full(jid)); _roster_free_walker(NULL, (const char *) jid_full(jid), (void *) item, NULL); - snprintf(filter, 4096, "(jid=%s)", jid_full(jid)); + snprintf(filter, 4096, "(jid=%i:%s)", strlen(jid_full(jid)), jid_full(jid)); storage_delete(sess->user->sm->st, "roster-items", jid_user(sess->jid), filter); - snprintf(filter, 4096, "(jid=%s)", jid_full(jid)); + snprintf(filter, 4096, "(jid=%i:%s)", strlen(jid_full(jid)), jid_full(jid)); storage_delete(sess->user->sm->st, "roster-groups", jid_user(sess->jid), filter); } diff -u sm.orig/mod_template_roster.c sm/mod_template_roster.c --- sm.orig/mod_template_roster.c Sat Nov 6 09:03:14 2004 +++ sm/mod_template_roster.c Sat Nov 6 09:56:28 2004 @@ -179,13 +179,13 @@ os_object_put(o, "from", &item->from, os_type_BOOLEAN); os_object_put(o, "ask", &item->ask, os_type_INTEGER); - snprintf(filter, 4096, "(jid=%s)", jid_full(item->jid)); + snprintf(filter, 4096, "(jid=%i:%s)", strlen(jid_full(item->jid)), jid_full(item->jid)); storage_replace(sm->st, "roster-items", jid_user(jid), filter, os); os_free(os); - snprintf(filter, 4096, "(jid=%s)", jid_full(item->jid)); + snprintf(filter, 4096, "(jid=%i:%s)", strlen(jid_full(item->jid)), jid_full(item->jid)); if(item->ngroups == 0) { storage_delete(sm->st, "roster-groups", jid_user(jid), filter); diff -u sm.orig/storage.c sm/storage.c --- sm.orig/storage.c Sat Nov 6 09:03:14 2004 +++ sm/storage.c Sat Nov 6 09:46:34 2004 @@ -324,12 +324,18 @@ static st_filter_t _storage_filter(pool p, const char *f, int len) { char *c, *key, *val, *sub; + int vallen; st_filter_t res, sf; if(f[0] != '(' && f[len] != ')') return NULL; /* key/value pair */ + + /* if value is numeric, then represented as is. */ + /* if value is string, it is preceded by length: e.g. "key=5:abcde" */ + /* (needed to pass values which include a closing bracket ')', e.g. in resourcenames */ + if(isalpha(f[1])) { key = strdup(f+1); @@ -342,13 +348,26 @@ val = c; - c = strchr(c, ')'); - if(c == NULL) { + /* decide whether number or string by checking for ':' before ')' */ + + while (*c != ':' && *c != ')' && *c) + c++; + + if (!*c) { free(key); return NULL; } - *c = '\0'; + if (*c == ':') { + /* string */ + *c = '\0'; + vallen = atoi(val); + c++; + val = c; + c += vallen; + } + + *c = '\0'; log_debug(ZONE, "extracted key %s val %s", key, val); res = pmalloco(p, sizeof(struct st_filter_st)); diff -u sm.orig/storage_mysql.c sm/storage_mysql.c --- sm.orig/storage_mysql.c Sat Nov 6 09:03:14 2004 +++ sm/storage_mysql.c Sat Nov 6 10:36:42 2004 @@ -73,13 +73,22 @@ /** this is the safety check used to make sure there's always enough mem */ #define MYSQL_SAFE(blocks, size, len) if((size) >= len) len = _st_mysql_realloc((void**)&(blocks),(size + 1)); -static void _st_mysql_convert_filter_recursive(st_filter_t f, char **buf, int *buflen, int *nbuf) { - st_filter_t scan; +static void _st_mysql_convert_filter_recursive(st_driver_t drv, st_filter_t f, char **buf, int *buflen, int *nbuf) { + drvdata_t data = (drvdata_t) drv->private; + st_filter_t scan; + char *cval; + int vlen; switch(f->type) { case st_filter_type_PAIR: - MYSQL_SAFE((*buf), *buflen + 12, *buflen); - *nbuf += sprintf(&((*buf)[*nbuf]), "( `%s` = \'%s\' ) ", f->key, f->val); + + /* do sql escape processing of f->val */ + cval = (char *) malloc(sizeof(char) * ((strlen((char *) f->val) * 2) + 1)); + vlen = mysql_real_escape_string(data->conn, cval, (char *) f->val, strlen((char *) f->val)); + + MYSQL_SAFE((*buf), *buflen + 12 + vlen - strlen(f->val), *buflen); + *nbuf += sprintf(&((*buf)[*nbuf]), "( `%s` = \'%s\' ) ", f->key, cval); + free(cval); break; @@ -88,7 +97,7 @@ *nbuf += sprintf(&((*buf)[*nbuf]), "( "); for(scan = f->sub; scan != NULL; scan = scan->next) { - _st_mysql_convert_filter_recursive(scan, buf, buflen, nbuf); + _st_mysql_convert_filter_recursive(drv, scan, buf, buflen, nbuf); if(scan->next != NULL) { MYSQL_SAFE((*buf), *buflen + 4, *buflen); @@ -106,7 +115,7 @@ *nbuf += sprintf(&((*buf)[*nbuf]), "( "); for(scan = f->sub; scan != NULL; scan = scan->next) { - _st_mysql_convert_filter_recursive(scan, buf, buflen, nbuf); + _st_mysql_convert_filter_recursive(drv, scan, buf, buflen, nbuf); if(scan->next != NULL) { MYSQL_SAFE((*buf), *buflen + 3, *buflen); @@ -123,7 +132,7 @@ MYSQL_SAFE((*buf), *buflen + 6, *buflen); *nbuf += sprintf(&((*buf)[*nbuf]), "( NOT "); - _st_mysql_convert_filter_recursive(f->sub, buf, buflen, nbuf); + _st_mysql_convert_filter_recursive(drv, f->sub, buf, buflen, nbuf); MYSQL_SAFE((*buf), *buflen + 2, *buflen); *nbuf += sprintf(&((*buf)[*nbuf]), ") "); @@ -160,7 +169,7 @@ fbuf = nbuf; - _st_mysql_convert_filter_recursive(f, &buf, &buflen, &nbuf); + _st_mysql_convert_filter_recursive(drv, f, &buf, &buflen, &nbuf); xhash_put(data->filters, cfilter, pstrdup(xhash_pool(data->filters), &buf[fbuf])); diff -u sm.orig/storage_pgsql.c sm/storage_pgsql.c --- sm.orig/storage_pgsql.c Sat Nov 6 09:03:14 2004 +++ sm/storage_pgsql.c Sat Nov 6 10:46:06 2004 @@ -61,13 +61,21 @@ /** this is the safety check used to make sure there's always enough mem */ #define PGSQL_SAFE(blocks, size, len) if((size) > len) len = _st_pgsql_realloc((void**)&(blocks),(size)); -static void _st_pgsql_convert_filter_recursive(st_filter_t f, char **buf, int *buflen, int *nbuf) { +static void _st_pgsql_convert_filter_recursive(st_driver_t drv, st_filter_t f, char **buf, int *buflen, int *nbuf) { + drvdata_t data = (drvdata_t) drv->private; st_filter_t scan; + int vlen; + char *cval; switch(f->type) { case st_filter_type_PAIR: - PGSQL_SAFE((*buf), *buflen + 12, *buflen); + /* do sql escaping for apostrophes */ + cval = (char *) malloc(sizeof(char) * ((strlen(f->val) * 2) + 1)); + vlen = PQescapeString(cval, f->val, strlen(f->val)); + + PGSQL_SAFE((*buf), *buflen + 12 + vlen - strlen(f->val), *buflen); *nbuf += sprintf(&((*buf)[*nbuf]), "( \"%s\" = \'%s\' ) ", f->key, f->val); + free(cval); break; @@ -76,7 +84,7 @@ *nbuf += sprintf(&((*buf)[*nbuf]), "( "); for(scan = f->sub; scan != NULL; scan = scan->next) { - _st_pgsql_convert_filter_recursive(scan, buf, buflen, nbuf); + _st_pgsql_convert_filter_recursive(drv, scan, buf, buflen, nbuf); if(scan->next != NULL) { PGSQL_SAFE((*buf), *buflen + 4, *buflen); @@ -94,7 +102,7 @@ *nbuf += sprintf(&((*buf)[*nbuf]), "( "); for(scan = f->sub; scan != NULL; scan = scan->next) { - _st_pgsql_convert_filter_recursive(scan, buf, buflen, nbuf); + _st_pgsql_convert_filter_recursive(drv, scan, buf, buflen, nbuf); if(scan->next != NULL) { PGSQL_SAFE((*buf), *buflen + 3, *buflen); @@ -111,7 +119,7 @@ PGSQL_SAFE((*buf), *buflen + 6, *buflen); *nbuf += sprintf(&((*buf)[*nbuf]), "( NOT "); - _st_pgsql_convert_filter_recursive(f->sub, buf, buflen, nbuf); + _st_pgsql_convert_filter_recursive(drv, f->sub, buf, buflen, nbuf); PGSQL_SAFE((*buf), *buflen + 2, *buflen); *nbuf += sprintf(&((*buf)[*nbuf]), ") "); @@ -148,7 +156,7 @@ fbuf = nbuf; - _st_pgsql_convert_filter_recursive(f, &buf, &buflen, &nbuf); + _st_pgsql_convert_filter_recursive(drv, f, &buf, &buflen, &nbuf); xhash_put(data->filters, cfilter, pstrdup(xhash_pool(data->filters), &buf[fbuf]));