Przeglądaj źródła

Merge pull request #1506 from guodongxiaren/printable_uri_check

check character validness in URI
Jiashun Zhu 2 lat temu
rodzic
commit
b8af1f1800
2 zmienionych plików z 27 dodań i 1 usunięć
  1. 23 1
      src/brpc/uri.cpp
  2. 4 0
      test/brpc_uri_unittest.cpp

+ 23 - 1
src/brpc/uri.cpp

@@ -16,6 +16,10 @@
 // under the License.
 
 
+#include <ctype.h>                         // isalnum
+
+#include <unordered_set>
+
 #include "brpc/log.h"
 #include "brpc/details/http_parser.h"      // http_parser_parse_url
 #include "brpc/uri.h"                      // URI
@@ -98,6 +102,21 @@ inline const char* SplitHostAndPort(const char* host_begin,
     return host_end;
 }
 
+// valid characters in URL
+// https://datatracker.ietf.org/doc/html/rfc3986#section-2.1
+// https://datatracker.ietf.org/doc/html/rfc3986#section-2.3
+// https://datatracker.ietf.org/doc/html/rfc3986#section-2.4
+// space is not allowed by rfc3986, but allowed by brpc
+static bool is_valid_char(char c) {
+    static const std::unordered_set<char> other_valid_char = {
+        ':', '/', '?', '#', '[', ']', '@', '!', '$', '&',
+        '\'', '(', ')', '*', '+', ',', ';', '=', '-', '.',
+        '_', '~', '%', ' '
+    };
+
+    return (isalnum(c) || other_valid_char.count(c));
+}
+
 static bool is_all_spaces(const char* p) {
     for (; *p == ' '; ++p) {}
     return !*p;
@@ -159,7 +178,10 @@ int URI::SetHttpURL(const char* url) {
         if (action == URI_PARSE_BREAK) {
             break;
         }
-        if (*p == ':') {
+        if (!is_valid_char(*p)) {
+            _st.set_error(EINVAL, "invalid character in url");
+            return -1;
+        } else if (*p == ':') {
             if (p[1] == '/' && p[2] == '/' && need_scheme) {
                 need_scheme = false;
                 _scheme.assign(start, p - start);

+ 4 - 0
test/brpc_uri_unittest.cpp

@@ -488,3 +488,7 @@ TEST(URITest, query_remover_key_value_not_changed_after_modified_query) {
     ASSERT_EQ(qr.value(), "value2");
 }
 
+TEST(URITest, valid_character) {
+    brpc::URI uri;
+    ASSERT_EQ(0, uri.SetHttpURL("www.baidu2.com':/?#[]@!$&()*+,;=-._~%"));
+}