diff --git a/cachedb/cachedb_id.c b/cachedb/cachedb_id.c index a4ae00505a1..b509d1a51e2 100644 --- a/cachedb/cachedb_id.c +++ b/cachedb/cachedb_id.c @@ -89,7 +89,7 @@ static int parse_cachedb_url(struct cachedb_id* id, const str* url) enum state st; unsigned int len, i, ipv6_flag=0, multi_hosts=0; - char* begin; + char* begin, *last_at; char* prev_token,*start_host=NULL,*start_prev=NULL,*ptr; prev_token = 0; @@ -112,6 +112,8 @@ static int parse_cachedb_url(struct cachedb_id* id, const str* url) if (dupl_string(&id->initial_url,url->s,url->s+url->len) < 0) goto err; + last_at = q_memrchr(url->s, '@', url->len); + for(i = 0; i < len; i++) { switch(st) { case ST_SCHEME: @@ -165,6 +167,9 @@ static int parse_cachedb_url(struct cachedb_id* id, const str* url) case ST_USER_HOST: switch(url->s[i]) { case '@': + if (&url->s[i] < last_at) + break; + st = ST_HOST; multi_hosts = 0; if (dupl_string(&id->username, begin, url->s + i) < 0) goto err; @@ -201,6 +206,9 @@ static int parse_cachedb_url(struct cachedb_id* id, const str* url) case ST_PASS_PORT: switch(url->s[i]) { case '@': + if (&url->s[i] < last_at) + break; + st = ST_HOST; id->username = prev_token; if (dupl_string(&id->password, begin, url->s + i) < 0) goto err; diff --git a/cachedb/test/test_cachedb.c b/cachedb/test/test_cachedb.c index 2fb3f0c28c3..3d640793e58 100644 --- a/cachedb/test/test_cachedb.c +++ b/cachedb/test/test_cachedb.c @@ -896,6 +896,30 @@ static void test_cachedb_url(void) ok(!strcmp(db->database, "d")); ok(db->port == 0); + CDB_PARSE("redis:group1://user:@,pwd,foo,@h1,h2,h3:6379/d"); + ok(db->flags == CACHEDB_ID_MULTIPLE_HOSTS); + ok(!strcmp(db->username, "user")); + ok(!strcmp(db->password, "@,pwd,foo,")); + ok(!strcmp(db->host, "h1,h2,h3:6379")); + ok(!strcmp(db->database, "d")); + ok(db->port == 0); + + CDB_PARSE("redis:group1://user:,pwd,@foo,@h1,h2,h3:6379/d"); + ok(db->flags == CACHEDB_ID_MULTIPLE_HOSTS); + ok(!strcmp(db->username, "user")); + ok(!strcmp(db->password, ",pwd,@foo,")); + ok(!strcmp(db->host, "h1,h2,h3:6379")); + ok(!strcmp(db->database, "d")); + ok(db->port == 0); + + CDB_PARSE("redis:group1://user:,pwd,foo,@@h1,h2,h3:6379/d"); + ok(db->flags == CACHEDB_ID_MULTIPLE_HOSTS); + ok(!strcmp(db->username, "user")); + ok(!strcmp(db->password, ",pwd,foo,@")); + ok(!strcmp(db->host, "h1,h2,h3:6379")); + ok(!strcmp(db->database, "d")); + ok(db->port == 0); + CDB_PARSE("redis:group1://:,pwd,foo,@h1,h2,h3:6379/d"); ok(db->flags == CACHEDB_ID_MULTIPLE_HOSTS); ok(!strcmp(db->username, ""));