Explorar el Código

fix: JSON-Pointer handling is looser in the schema handler than the format handler

Sam Jaffe hace 3 meses
padre
commit
68804cd7c3
Se han modificado 2 ficheros con 15 adiciones y 3 borrados
  1. 7 2
      include/jvalidate/detail/pointer.h
  2. 8 1
      include/jvalidate/format.h

+ 7 - 2
include/jvalidate/detail/pointer.h

@@ -3,6 +3,7 @@
 #include <algorithm>
 #include <cassert>
 #include <iostream>
+#include <jvalidate/detail/expect.h>
 #include <jvalidate/detail/number.h>
 #include <string>
 #include <string_view>
@@ -42,7 +43,7 @@ public:
    * valid - and therefore that an invalidly formatter pointer string will
    * point to somewhere non-existant (since it will be used in schema handling)
    */
-  Pointer(std::string_view path) {
+  Pointer(std::string_view path, bool strict = false) {
     if (path.empty()) {
       return;
     }
@@ -63,8 +64,9 @@ public:
         // than '/' and '~' to be handled in all contexts.
         // TODO(samjaffe): Only do this if enc is hex-like (currently throws?)
         if (in[i] == '%') {
-          char const enc[3] = {in[i + 1], in[i + 2], '\0'};
+          std::string_view enc = std::string_view(in).substr(i + 1, 2);
           in.replace(i, 3, 1, from_str<char>(enc, 16));
+          continue;
         } else if (in[i] != '~') {
           // Not a special char-sequence, does not need massaging
           continue;
@@ -77,6 +79,8 @@ public:
           in.replace(i, 2, 1, '~');
         } else if (in[i + 1] == '1') {
           in.replace(i, 2, 1, '/');
+        } else {
+          JVALIDATE_THROW(std::runtime_error, "Illegal ~ code");
         }
       }
       tokens_.push_back(std::move(in));
@@ -84,6 +88,7 @@ public:
 
     // JSON-Pointers are required to start with a '/' although we only enforce
     // that rule in Reference.
+    EXPECT_M(not strict || path.starts_with('/'), "JSON Pointer must start with '/'");
     path.remove_prefix(1);
     // The rules of JSON-Pointer is that if a token were to contain a '/' as a
     // strict character: then that character would be escaped, using the above

+ 8 - 1
include/jvalidate/format.h

@@ -273,6 +273,13 @@ template <typename T> inline bool ctor_as_valid(std::string_view str) {
     return true;
   } catch (std::exception const &) { return false; }
 }
+
+inline bool json_pointer(std::string_view ptr) {
+  try {
+    [[maybe_unused]] ::jvalidate::detail::Pointer _{ptr, true};
+    return true;
+  } catch (std::exception const & ex) { return false; }
+}
 }
 
 namespace jvalidate {
@@ -294,7 +301,7 @@ private:
       {"ipv6", &format::ipv6},
       {"iri", nullptr},
       {"iri-reference", nullptr},
-      {"json-pointer", &format::ctor_as_valid<detail::Pointer>},
+      {"json-pointer", &format::json_pointer},
       {"relative-json-pointer", &format::ctor_as_valid<detail::RelativePointer>},
       /* {"regex", &detail::StdRegexEngine::is_valid}, */
       {"time", &format::time},