File Coverage

amqp_url.c
Criterion Covered Total %
statement 0 79 0.0
branch 0 52 0.0
condition n/a
subroutine n/a
pod n/a
total 0 131 0.0


line stmt bran cond sub pod time code
1             /*
2             * ***** BEGIN LICENSE BLOCK *****
3             * Version: MIT
4             *
5             * Portions created by Alan Antonuk are Copyright (c) 2012-2013
6             * Alan Antonuk. All Rights Reserved.
7             *
8             * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
9             * All Rights Reserved.
10             *
11             * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
12             * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
13             *
14             * Permission is hereby granted, free of charge, to any person
15             * obtaining a copy of this software and associated documentation
16             * files (the "Software"), to deal in the Software without
17             * restriction, including without limitation the rights to use, copy,
18             * modify, merge, publish, distribute, sublicense, and/or sell copies
19             * of the Software, and to permit persons to whom the Software is
20             * furnished to do so, subject to the following conditions:
21             *
22             * The above copyright notice and this permission notice shall be
23             * included in all copies or substantial portions of the Software.
24             *
25             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29             * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30             * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31             * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32             * SOFTWARE.
33             * ***** END LICENSE BLOCK *****
34             */
35              
36             #ifdef HAVE_CONFIG_H
37             #include "config.h"
38             #endif
39              
40             #ifdef _MSC_VER
41             #define _CRT_SECURE_NO_WARNINGS
42             #endif
43              
44             #include "amqp_private.h"
45             #include
46             #include
47             #include
48             #include
49             #include
50              
51 0           void amqp_default_connection_info(struct amqp_connection_info *ci) {
52             /* Apply defaults */
53 0           ci->user = "guest";
54 0           ci->password = "guest";
55 0           ci->host = "localhost";
56 0           ci->port = 5672;
57 0           ci->vhost = "/";
58 0           ci->ssl = 0;
59 0           }
60              
61             /* Scan for the next delimiter, handling percent-encodings on the way. */
62 0           static char find_delim(char **pp, int colon_and_at_sign_are_delims) {
63 0           char *from = *pp;
64 0           char *to = from;
65              
66             for (;;) {
67 0           char ch = *from++;
68              
69 0           switch (ch) {
70             case ':':
71             case '@':
72 0 0         if (!colon_and_at_sign_are_delims) {
73 0           *to++ = ch;
74 0           break;
75             }
76              
77             /* fall through */
78             case 0:
79             case '/':
80             case '?':
81             case '#':
82             case '[':
83             case ']':
84 0           *to = 0;
85 0           *pp = from;
86 0           return ch;
87              
88             case '%': {
89             unsigned int val;
90             int chars;
91 0           int res = sscanf(from, "%2x%n", &val, &chars);
92              
93 0 0         if (res == EOF || res < 1 || chars != 2 || val > CHAR_MAX)
    0          
    0          
    0          
94             /* Return a surprising delimiter to
95             force an error. */
96             {
97 0           return '%';
98             }
99              
100 0           *to++ = (char)val;
101 0           from += 2;
102 0           break;
103             }
104              
105             default:
106 0           *to++ = ch;
107 0           break;
108             }
109 0           }
110             }
111              
112             /* Parse an AMQP URL into its component parts. */
113 0           int amqp_parse_url(char *url, struct amqp_connection_info *parsed) {
114 0           int res = AMQP_STATUS_BAD_URL;
115             char delim;
116             char *start;
117             char *host;
118 0           char *port = NULL;
119              
120 0           amqp_default_connection_info(parsed);
121              
122             /* check the prefix */
123 0 0         if (!strncmp(url, "amqp://", 7)) {
124             /* do nothing */
125 0 0         } else if (!strncmp(url, "amqps://", 8)) {
126 0           parsed->port = 5671;
127 0           parsed->ssl = 1;
128             } else {
129 0           goto out;
130             }
131              
132 0 0         host = start = url += (parsed->ssl ? 8 : 7);
133 0           delim = find_delim(&url, 1);
134              
135 0 0         if (delim == ':') {
136             /* The colon could be introducing the port or the
137             password part of the userinfo. We don't know yet,
138             so stash the preceding component. */
139 0           port = start = url;
140 0           delim = find_delim(&url, 1);
141             }
142              
143 0 0         if (delim == '@') {
144             /* What might have been the host and port were in fact
145             the username and password */
146 0           parsed->user = host;
147 0 0         if (port) {
148 0           parsed->password = port;
149             }
150              
151 0           port = NULL;
152 0           host = start = url;
153 0           delim = find_delim(&url, 1);
154             }
155              
156 0 0         if (delim == '[') {
157             /* IPv6 address. The bracket should be the first
158             character in the host. */
159 0 0         if (host != start || *host != 0) {
    0          
160             goto out;
161             }
162              
163 0           start = url;
164 0           delim = find_delim(&url, 0);
165              
166 0 0         if (delim != ']') {
167 0           goto out;
168             }
169              
170 0           parsed->host = start;
171 0           start = url;
172 0           delim = find_delim(&url, 1);
173              
174             /* Closing bracket should be the last character in the
175             host. */
176 0 0         if (*start != 0) {
177 0           goto out;
178             }
179             } else {
180             /* If we haven't seen the host yet, this is it. */
181 0 0         if (*host != 0) {
182 0           parsed->host = host;
183             }
184             }
185              
186 0 0         if (delim == ':') {
187 0           port = start = url;
188 0           delim = find_delim(&url, 1);
189             }
190              
191 0 0         if (port) {
192             char *end;
193 0           long portnum = strtol(port, &end, 10);
194              
195 0 0         if (port == end || *end != 0 || portnum < 0 || portnum > 65535) {
    0          
    0          
    0          
196             goto out;
197             }
198              
199 0           parsed->port = portnum;
200             }
201              
202 0 0         if (delim == '/') {
203 0           start = url;
204 0           delim = find_delim(&url, 1);
205              
206 0 0         if (delim != 0) {
207 0           goto out;
208             }
209              
210 0           parsed->vhost = start;
211 0           res = AMQP_STATUS_OK;
212 0 0         } else if (delim == 0) {
213 0           res = AMQP_STATUS_OK;
214             }
215              
216             /* Any other delimiter is bad, and we will return AMQP_STATUS_BAD_AMQP_URL. */
217              
218             out:
219 0           return res;
220             }