aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/scheme/tests/fuzz_json/lib
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/scheme/tests/fuzz_json/lib
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/scheme/tests/fuzz_json/lib')
-rw-r--r--library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.cpp115
-rw-r--r--library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.h7
-rw-r--r--library/cpp/scheme/tests/fuzz_json/lib/ya.make18
3 files changed, 140 insertions, 0 deletions
diff --git a/library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.cpp b/library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.cpp
new file mode 100644
index 0000000000..7c16527c23
--- /dev/null
+++ b/library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.cpp
@@ -0,0 +1,115 @@
+#include "fuzz_json.h"
+#include "util/generic/fwd.h"
+
+#include <library/cpp/scheme/scheme.h>
+#include <util/stream/null.h>
+
+namespace {
+ static constexpr size_t MAX_DEPTH = 4;
+ static constexpr size_t MAX_PATH_LEN = 256;
+ static constexpr size_t MAX_ITERATIONS = 4;
+
+ void SplitOnDepth(const TStringBuf src, const size_t depth, const size_t maxPathLen,
+ TStringBuf& left, TStringBuf& right)
+ {
+ size_t pos = 0;
+ size_t prevPos = 0;
+ for(size_t i = 0; i < depth; ++i) {
+ if (pos > maxPathLen) {
+ break;
+ }
+ prevPos = pos;
+ pos = src.find_first_of(TStringBuf("/]"), pos + 1);
+ if (pos == TStringBuf::npos) {
+ break;
+ }
+ }
+ if (pos == TStringBuf::npos && prevPos > 0) {
+ pos = prevPos;
+ }
+ if (src.length() > maxPathLen) {
+ if (pos == TStringBuf::npos || pos > maxPathLen) {
+ pos = maxPathLen;
+ }
+ }
+ if (pos == TStringBuf::npos || pos == 0) {
+ left = src;
+ right = TStringBuf();
+ } else {
+ src.SplitAt(pos + 1, left, right);
+ }
+ }
+
+ TString tmp;
+ //Limit max array size in the path to 256
+ TStringBuf ProcessPath(TStringBuf path) {
+ size_t pos = 0;
+ while(pos != TStringBuf::npos) {
+ pos = path.find(']', pos + 1);
+ if (pos == TStringBuf::npos) {
+ continue;
+ }
+ size_t open = path.rfind('[', pos);
+ if (open == TStringBuf::npos) {
+ continue;
+ }
+ bool allDigit = true;
+ for(size_t i = open + 1; i < pos; ++i) {
+ if (path[i] < '0' || path[i] > '9') {
+ allDigit = false;
+ break;
+ }
+ }
+ if (!allDigit) {
+ continue;
+ }
+ if (pos - open > 4) {
+ TString str = TString::Join(path.Head(open + 1), "256", path.Tail(pos));
+ tmp = std::move(str);
+ path = tmp;
+ pos = (open + 1) + 3;
+ continue;
+ }
+ }
+ return path;
+ }
+}
+
+namespace NSc::NUt {
+
+
+ void FuzzJson(TStringBuf wire) {
+ if (wire.size() < 2) {
+ return;
+ }
+
+
+ ProcessPath("[123][1234][12][2134][12312312][1][12]");
+ ui8 len1 = wire[0];
+ ui8 len2 = wire[1];
+ wire.Skip(2);
+ auto json1 = wire.NextTokAt(len1);
+ auto json2 = wire.NextTokAt(len2);
+ NSc::TValue val1 = NSc::TValue::FromJson(json1);
+ NSc::TValue val2 = NSc::TValue::FromJson(json2);
+ NSc::TValue val3;
+ val3.MergeUpdate(val1);
+
+ size_t i = 0;
+ while (!wire.empty()) {
+ TStringBuf path;
+ SplitOnDepth(wire, MAX_DEPTH, MAX_PATH_LEN, path, wire);
+ path = ProcessPath(path);
+ if (auto* target = val3.TrySelectOrAdd(path)) {
+ target->MergeUpdate(val2);
+ }
+ ++i;
+ // Release memory since there are up to MAX_DICT_SIZE * MAX_DEPTH elements
+ if (i > MAX_ITERATIONS) {
+ Cnull << val3.ToJson();
+ val3 = NSc::TValue();
+ }
+ }
+ Cnull << val3.ToJson();
+ }
+}
diff --git a/library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.h b/library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.h
new file mode 100644
index 0000000000..f8cf7a4770
--- /dev/null
+++ b/library/cpp/scheme/tests/fuzz_json/lib/fuzz_json.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <util/generic/strbuf.h>
+
+namespace NSc::NUt {
+ void FuzzJson(TStringBuf wire);
+}
diff --git a/library/cpp/scheme/tests/fuzz_json/lib/ya.make b/library/cpp/scheme/tests/fuzz_json/lib/ya.make
new file mode 100644
index 0000000000..b30a6c9350
--- /dev/null
+++ b/library/cpp/scheme/tests/fuzz_json/lib/ya.make
@@ -0,0 +1,18 @@
+LIBRARY()
+
+OWNER(
+ g:blender
+ g:middle
+ g:upper
+ velavokr
+)
+
+SRCS(
+ fuzz_json.cpp
+)
+
+PEERDIR(
+ library/cpp/scheme
+)
+
+END()