|
@@ -364,42 +364,55 @@ read_escaped_data(const char *data, size_t len, char **out)
|
|
return outp - *out;
|
|
return outp - *out;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
+
|
|
-static const char *
|
|
+ * double-quoted string with escaped characters, return the length of that
|
|
-extract_escaped_string(const char *start, size_t in_len_max,
|
|
+ * string (as encoded, including quotes). Otherwise return -1. */
|
|
- char **out, size_t *out_len)
|
|
+static INLINE int
|
|
|
|
+get_escaped_string_length(const char *start, size_t in_len_max,
|
|
|
|
+ int *chars_out)
|
|
{
|
|
{
|
|
const char *cp, *end;
|
|
const char *cp, *end;
|
|
- size_t len=0;
|
|
+ int chars = 0;
|
|
|
|
|
|
if (*start != '\"')
|
|
if (*start != '\"')
|
|
- return NULL;
|
|
+ return -1;
|
|
|
|
|
|
cp = start+1;
|
|
cp = start+1;
|
|
end = start+in_len_max;
|
|
end = start+in_len_max;
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
while (1) {
|
|
- if (cp >= end)
|
|
+ if (cp >= end) {
|
|
- return NULL;
|
|
+ return -1;
|
|
- else if (*cp == '\\') {
|
|
+ } else if (*cp == '\\') {
|
|
if (++cp == end)
|
|
if (++cp == end)
|
|
- return NULL;
|
|
+ return -1;
|
|
++cp;
|
|
++cp;
|
|
- ++len;
|
|
+ ++chars;
|
|
} else if (*cp == '\"') {
|
|
} else if (*cp == '\"') {
|
|
break;
|
|
break;
|
|
} else {
|
|
} else {
|
|
++cp;
|
|
++cp;
|
|
- ++len;
|
|
+ ++chars;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- end = cp;
|
|
+ if (chars_out)
|
|
|
|
+ *chars_out = chars;
|
|
|
|
+ return cp - start+1;
|
|
|
|
+}
|
|
|
|
|
|
- *out_len = end-start+1;
|
|
+
|
|
|
|
+ * entire thing, including quotation marks. */
|
|
|
|
+static const char *
|
|
|
|
+extract_escaped_string(const char *start, size_t in_len_max,
|
|
|
|
+ char **out, size_t *out_len)
|
|
|
|
+{
|
|
|
|
+ int length = get_escaped_string_length(start, in_len_max, NULL);
|
|
|
|
+ if (length<0)
|
|
|
|
+ return NULL;
|
|
|
|
+ *out_len = length;
|
|
*out = tor_strndup(start, *out_len);
|
|
*out = tor_strndup(start, *out_len);
|
|
-
|
|
+ return start+length;
|
|
- return end+1;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -410,40 +423,22 @@ extract_escaped_string(const char *start, size_t in_len_max,
|
|
* store its length in <b>out_len</b>. On success, return a pointer to the
|
|
* store its length in <b>out_len</b>. On success, return a pointer to the
|
|
* character immediately following the escaped string. On failure, return
|
|
* character immediately following the escaped string. On failure, return
|
|
* NULL. */
|
|
* NULL. */
|
|
-
|
|
|
|
static const char *
|
|
static const char *
|
|
-get_escaped_string(const char *start, size_t in_len_max,
|
|
+decode_escaped_string(const char *start, size_t in_len_max,
|
|
char **out, size_t *out_len)
|
|
char **out, size_t *out_len)
|
|
{
|
|
{
|
|
const char *cp, *end;
|
|
const char *cp, *end;
|
|
char *outp;
|
|
char *outp;
|
|
- size_t len=0;
|
|
+ int len, n_chars = 0;
|
|
|
|
|
|
- if (*start != '\"')
|
|
+ len = get_escaped_string_length(start, in_len_max, &n_chars);
|
|
|
|
+ if (len<0)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
- cp = start+1;
|
|
+ end = start+len-1;
|
|
- end = start+in_len_max;
|
|
+ tor_assert(*end == '\"');
|
|
-
|
|
|
|
-
|
|
|
|
- while (1) {
|
|
|
|
- if (cp >= end)
|
|
|
|
- return NULL;
|
|
|
|
- else if (*cp == '\\') {
|
|
|
|
- if (++cp == end)
|
|
|
|
- return NULL;
|
|
|
|
- ++cp;
|
|
|
|
- ++len;
|
|
|
|
- } else if (*cp == '\"') {
|
|
|
|
- break;
|
|
|
|
- } else {
|
|
|
|
- ++cp;
|
|
|
|
- ++len;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- end = cp;
|
|
|
|
outp = *out = tor_malloc(len+1);
|
|
outp = *out = tor_malloc(len+1);
|
|
- *out_len = len;
|
|
+ *out_len = n_chars;
|
|
|
|
|
|
cp = start+1;
|
|
cp = start+1;
|
|
while (cp < end) {
|
|
while (cp < end) {
|
|
@@ -1030,7 +1025,7 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
|
|
password = tor_strdup("");
|
|
password = tor_strdup("");
|
|
password_len = 0;
|
|
password_len = 0;
|
|
} else {
|
|
} else {
|
|
- if (!get_escaped_string(body, len, &password, &password_len)) {
|
|
+ if (!decode_escaped_string(body, len, &password, &password_len)) {
|
|
connection_write_str_to_buf("551 Invalid quoted string. You need "
|
|
connection_write_str_to_buf("551 Invalid quoted string. You need "
|
|
"to put the password in double quotes.\r\n", conn);
|
|
"to put the password in double quotes.\r\n", conn);
|
|
connection_mark_for_close(TO_CONN(conn));
|
|
connection_mark_for_close(TO_CONN(conn));
|