parent
6336183221
commit
b6effa6be1
@ -0,0 +1,198 @@
|
|||||||
|
From ea875055e446da8514b10e3b6af0942997544af0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Conway <aconway@redhat.com>
|
||||||
|
Date: Wed, 10 May 2017 16:30:14 -0400
|
||||||
|
Subject: [PATCH] PROTON-1466: proton-c mixing up links with names that are
|
||||||
|
prefixes
|
||||||
|
|
||||||
|
Creating links where one link name is a prefix of the other, e.g. "xx" and
|
||||||
|
"xxyy" sometimes caused the links to be confused.
|
||||||
|
---
|
||||||
|
proton-c/src/core/codec.c | 2 +-
|
||||||
|
proton-c/src/core/transport.c | 14 +++++------
|
||||||
|
proton-c/src/core/util.h | 11 +++++++++
|
||||||
|
proton-c/src/extra/scanner.c | 8 ++++---
|
||||||
|
proton-c/src/tests/engine.c | 55 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
5 files changed, 79 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/proton-c/src/core/codec.c b/proton-c/src/core/codec.c
|
||||||
|
index 67769ad..7809907 100644
|
||||||
|
--- a/proton-c/src/core/codec.c
|
||||||
|
+++ b/proton-c/src/core/codec.c
|
||||||
|
@@ -1328,7 +1328,7 @@ bool pn_data_lookup(pn_data_t *data, const char *name)
|
||||||
|
case PN_SYMBOL:
|
||||||
|
{
|
||||||
|
pn_bytes_t bytes = pn_data_get_bytes(data);
|
||||||
|
- if (strlen(name) == bytes.size && !strncmp(name, bytes.start, bytes.size)) {
|
||||||
|
+ if (pn_bytes_equal(bytes, pn_bytes(strlen(name), name))) {
|
||||||
|
return pn_data_next(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/proton-c/src/core/transport.c b/proton-c/src/core/transport.c
|
||||||
|
index 8777318..f9eea7b 100644
|
||||||
|
--- a/proton-c/src/core/transport.c
|
||||||
|
+++ b/proton-c/src/core/transport.c
|
||||||
|
@@ -1277,7 +1277,7 @@ pn_link_t *pn_find_link(pn_session_t *ssn, pn_bytes_t name, bool is_sender)
|
||||||
|
// which is closed both locally and remotely, assume that is
|
||||||
|
// no longer in use.
|
||||||
|
!((link->endpoint.state & PN_LOCAL_CLOSED) && (link->endpoint.state & PN_REMOTE_CLOSED)) &&
|
||||||
|
- !strncmp(name.start, pn_string_get(link->name), name.size))
|
||||||
|
+ pn_bytes_equal(name, pn_string_bytes(link->name)))
|
||||||
|
{
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
@@ -1290,13 +1290,13 @@ static pn_expiry_policy_t symbol2policy(pn_bytes_t symbol)
|
||||||
|
if (!symbol.start)
|
||||||
|
return PN_EXPIRE_WITH_SESSION;
|
||||||
|
|
||||||
|
- if (!strncmp(symbol.start, "link-detach", symbol.size))
|
||||||
|
+ if (pn_bytes_equal(symbol, PN_BYTES_LITERAL(link-detach)))
|
||||||
|
return PN_EXPIRE_WITH_LINK;
|
||||||
|
- if (!strncmp(symbol.start, "session-end", symbol.size))
|
||||||
|
+ if (pn_bytes_equal(symbol, PN_BYTES_LITERAL(session-end)))
|
||||||
|
return PN_EXPIRE_WITH_SESSION;
|
||||||
|
- if (!strncmp(symbol.start, "connection-close", symbol.size))
|
||||||
|
+ if (pn_bytes_equal(symbol, PN_BYTES_LITERAL(connection-close)))
|
||||||
|
return PN_EXPIRE_WITH_CONNECTION;
|
||||||
|
- if (!strncmp(symbol.start, "never", symbol.size))
|
||||||
|
+ if (pn_bytes_equal(symbol, PN_BYTES_LITERAL(never)))
|
||||||
|
return PN_EXPIRE_NEVER;
|
||||||
|
|
||||||
|
return PN_EXPIRE_WITH_SESSION;
|
||||||
|
@@ -1307,9 +1307,9 @@ static pn_distribution_mode_t symbol2dist_mode(const pn_bytes_t symbol)
|
||||||
|
if (!symbol.start)
|
||||||
|
return PN_DIST_MODE_UNSPECIFIED;
|
||||||
|
|
||||||
|
- if (!strncmp(symbol.start, "move", symbol.size))
|
||||||
|
+ if (pn_bytes_equal(symbol, PN_BYTES_LITERAL(move)))
|
||||||
|
return PN_DIST_MODE_MOVE;
|
||||||
|
- if (!strncmp(symbol.start, "copy", symbol.size))
|
||||||
|
+ if (pn_bytes_equal(symbol, PN_BYTES_LITERAL(copy)))
|
||||||
|
return PN_DIST_MODE_COPY;
|
||||||
|
|
||||||
|
return PN_DIST_MODE_UNSPECIFIED;
|
||||||
|
diff --git a/proton-c/src/core/util.h b/proton-c/src/core/util.h
|
||||||
|
index b54f689..4d3ba3b 100644
|
||||||
|
--- a/proton-c/src/core/util.h
|
||||||
|
+++ b/proton-c/src/core/util.h
|
||||||
|
@@ -44,6 +44,17 @@ char *pn_strndup(const char *src, size_t n);
|
||||||
|
int pn_strcasecmp(const char* a, const char* b);
|
||||||
|
int pn_strncasecmp(const char* a, const char* b, size_t len);
|
||||||
|
|
||||||
|
+static inline bool pn_bytes_equal(const pn_bytes_t a, const pn_bytes_t b) {
|
||||||
|
+ return (a.size == b.size && !memcmp(a.start, b.start, a.size));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline pn_bytes_t pn_string_bytes(pn_string_t *s) {
|
||||||
|
+ return pn_bytes(pn_string_size(s), pn_string_get(s));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Create a literal bytes value, e.g. PN_BYTES_LITERAL(foo) == pn_bytes(3, "foo") */
|
||||||
|
+#define PN_BYTES_LITERAL(X) (pn_bytes(sizeof(#X)-1, #X))
|
||||||
|
+
|
||||||
|
#define DIE_IFR(EXPR, STRERR) \
|
||||||
|
do { \
|
||||||
|
int __code__ = (EXPR); \
|
||||||
|
diff --git a/proton-c/src/extra/scanner.c b/proton-c/src/extra/scanner.c
|
||||||
|
index beb7322..99c35d2 100644
|
||||||
|
--- a/proton-c/src/extra/scanner.c
|
||||||
|
+++ b/proton-c/src/extra/scanner.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "scanner.h"
|
||||||
|
+#include "../core/util.h"
|
||||||
|
|
||||||
|
#include "platform/platform.h"
|
||||||
|
|
||||||
|
@@ -217,12 +218,13 @@ static int pni_scanner_alpha_end(pn_scanner_t *scanner, const char *str, int sta
|
||||||
|
static int pni_scanner_alpha(pn_scanner_t *scanner, const char *str)
|
||||||
|
{
|
||||||
|
int n = pni_scanner_alpha_end(scanner, str, 0);
|
||||||
|
+ pn_bytes_t b = pn_bytes(n, str);
|
||||||
|
pn_token_type_t type;
|
||||||
|
- if (!strncmp(str, "true", n)) {
|
||||||
|
+ if (pn_bytes_equal(b, PN_BYTES_LITERAL(true))) {
|
||||||
|
type = PN_TOK_TRUE;
|
||||||
|
- } else if (!strncmp(str, "false", n)) {
|
||||||
|
+ } else if (pn_bytes_equal(b, PN_BYTES_LITERAL(false))) {
|
||||||
|
type = PN_TOK_FALSE;
|
||||||
|
- } else if (!strncmp(str, "null", n)) {
|
||||||
|
+ } else if (pn_bytes_equal(b, PN_BYTES_LITERAL(null))) {
|
||||||
|
type = PN_TOK_NULL;
|
||||||
|
} else {
|
||||||
|
type = PN_TOK_ID;
|
||||||
|
diff --git a/proton-c/src/tests/engine.c b/proton-c/src/tests/engine.c
|
||||||
|
index 87d8d95..41d17a0 100644
|
||||||
|
--- a/proton-c/src/tests/engine.c
|
||||||
|
+++ b/proton-c/src/tests/engine.c
|
||||||
|
@@ -294,12 +294,67 @@ int test_free_link(int argc, char **argv)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+// regression test fo PROTON-1466 - confusion between links with prefix names
|
||||||
|
+static int test_link_name_prefix(int argc, char **argv)
|
||||||
|
+{
|
||||||
|
+ fprintf(stdout, "test_link_name_prefix\n");
|
||||||
|
+ pn_connection_t *c1 = pn_connection();
|
||||||
|
+ pn_transport_t *t1 = pn_transport();
|
||||||
|
+ pn_transport_bind(t1, c1);
|
||||||
|
+
|
||||||
|
+ pn_connection_t *c2 = pn_connection();
|
||||||
|
+ pn_transport_t *t2 = pn_transport();
|
||||||
|
+ pn_transport_set_server(t2);
|
||||||
|
+ pn_transport_bind(t2, c2);
|
||||||
|
+
|
||||||
|
+ pn_connection_open(c1);
|
||||||
|
+ pn_connection_open(c2);
|
||||||
|
+
|
||||||
|
+ pn_session_t *s1 = pn_session(c1);
|
||||||
|
+ pn_session_open(s1);
|
||||||
|
+
|
||||||
|
+ pn_link_t *l = pn_receiver(s1, "l");
|
||||||
|
+ pn_link_open(l);
|
||||||
|
+ pn_link_t *lll = pn_receiver(s1, "lll");
|
||||||
|
+ pn_link_open(lll);
|
||||||
|
+ pn_link_t *ll = pn_receiver(s1, "ll");
|
||||||
|
+ pn_link_open(ll);
|
||||||
|
+
|
||||||
|
+ while (pump(t1, t2)) {
|
||||||
|
+ process_endpoints(c1);
|
||||||
|
+ process_endpoints(c2);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // session and link should be up, c2 should have a receiver link:
|
||||||
|
+ assert(pn_session_state( s1 ) == (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE));
|
||||||
|
+ assert(pn_link_state( l ) == (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE));
|
||||||
|
+ assert(pn_link_state( lll ) == (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE));
|
||||||
|
+ assert(pn_link_state( ll ) == (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE));
|
||||||
|
+
|
||||||
|
+ pn_link_t *r = pn_link_head(c2, (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE));
|
||||||
|
+ assert(!strcmp(pn_link_name(r), "l"));
|
||||||
|
+ r = pn_link_next(r, (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE));
|
||||||
|
+ assert(!strcmp(pn_link_name(r), "lll"));
|
||||||
|
+ r = pn_link_next(r, (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE));
|
||||||
|
+ assert(!strcmp(pn_link_name(r), "ll"));
|
||||||
|
+
|
||||||
|
+ pn_transport_unbind(t1);
|
||||||
|
+ pn_transport_free(t1);
|
||||||
|
+ pn_connection_free(c1);
|
||||||
|
+
|
||||||
|
+ pn_transport_unbind(t2);
|
||||||
|
+ pn_transport_free(t2);
|
||||||
|
+ pn_connection_free(c2);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
|
||||||
|
typedef int (*test_ptr_t)(int argc, char **argv);
|
||||||
|
|
||||||
|
test_ptr_t tests[] = {test_free_connection,
|
||||||
|
test_free_session,
|
||||||
|
test_free_link,
|
||||||
|
+ test_link_name_prefix,
|
||||||
|
NULL};
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
--
|
||||||
|
2.9.3
|
||||||
|
|
Loading…
Reference in new issue