Explorar el Código

fix: add support for non_bmp_regex

Sam Jaffe hace 1 año
padre
commit
2ff66e2e0c
Se han modificado 3 ficheros con 44 adiciones y 2 borrados
  1. 1 1
      Makefile
  2. 42 0
      include/jvalidate/detail/string.h
  3. 1 1
      include/jvalidate/validator.h

+ 1 - 1
Makefile

@@ -24,7 +24,7 @@ TEST_SOURCES := $(wildcard $(TEST_DIR)*.cxx)
 TEST_OBJECTS := $(patsubst %.cxx, .build/%.o, $(TEST_SOURCES))
 TEST_BINARIES := .build/bin/selfvalidate
 
-EXCLUDED_TESTS := format* content non_bmp_regex ecmascript_regex \
+EXCLUDED_TESTS := format* content ecmascript_regex \
 		  bignum float_overflow zeroTerminatedFloats
 EXCLUDED_TESTS := $(shell printf ":*optional_%s" $(EXCLUDED_TESTS) | cut -c2-)
 

+ 42 - 0
include/jvalidate/detail/string.h

@@ -1,6 +1,8 @@
+#pragma once
 
 #if __has_include(<unicode/std_string.h>)
 #define JVALIDATE_HAS_ICU
+#include <unicode/brkiter.h>
 #include <unicode/unistr.h>
 #endif
 
@@ -13,4 +15,44 @@ inline size_t length(std::string_view arg) {
   return arg.size();
 #endif
 }
+
+inline std::string regex_escape(std::string_view arg) {
+#ifdef JVALIDATE_HAS_ICU
+  icu::UnicodeString const ucs = icu::UnicodeString::fromUTF8(icu::StringPiece(arg));
+  if (ucs.countChar32() == arg.size()) {
+    return std::string(arg);
+  }
+
+  UErrorCode status = U_ZERO_ERROR;
+  std::unique_ptr<icu::BreakIterator> iter(
+      icu::BreakIterator::createCharacterInstance(NULL, status));
+
+  if (U_FAILURE(status)) {
+    return std::string(arg);
+  }
+
+  icu::UnicodeString rval;
+  iter->setText(ucs);
+  int32_t start = iter->first();
+  int32_t end = iter->next();
+  while (end != icu::BreakIterator::DONE) {
+    if (std::strchr("?*+", ucs.charAt(end))) {
+      rval.append('(');
+      rval.append(ucs, start, end - 1);
+      rval.append(')');
+      rval.append(ucs.char32At(end));
+      end = iter->next();
+    } else {
+      rval.append(ucs, start, end - 1);
+    }
+    start = end;
+    end = iter->next();
+  }
+
+  std::string out;
+  return rval.toUTF8String(out);
+#else
+  return std::string(arg);
+#endif
+}
 }

+ 1 - 1
include/jvalidate/validator.h

@@ -14,7 +14,7 @@ public:
   std::regex regex_;
 
 public:
-  StdRegexEngine(std::string const & regex) : regex_(regex) {}
+  StdRegexEngine(std::string const & regex) : regex_(detail::regex_escape(regex)) {}
   bool search(std::string const & text) const { return std::regex_search(text, regex_); }
 };
 }