aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/scheme/tests/fuzz_ops/lib/vm_parse.cpp
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_ops/lib/vm_parse.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/scheme/tests/fuzz_ops/lib/vm_parse.cpp')
-rw-r--r--library/cpp/scheme/tests/fuzz_ops/lib/vm_parse.cpp265
1 files changed, 265 insertions, 0 deletions
diff --git a/library/cpp/scheme/tests/fuzz_ops/lib/vm_parse.cpp b/library/cpp/scheme/tests/fuzz_ops/lib/vm_parse.cpp
new file mode 100644
index 0000000000..a03f5aef53
--- /dev/null
+++ b/library/cpp/scheme/tests/fuzz_ops/lib/vm_parse.cpp
@@ -0,0 +1,265 @@
+#include "vm_parse.h"
+
+namespace NSc::NUt {
+#define Y_TRY_READ_BITS(state, out, bits, res) do { if (!state.Input.Read(out, bits)) { return res; } } while (false)
+#define Y_TRY_READ_BITS_BOOL(state, out, bits) Y_TRY_READ_BITS(state, out, bits, false)
+#define Y_TRY_READ_BITS_MAYBE(state, out, bits) Y_TRY_READ_BITS(state, out, bits, Nothing())
+
+ TMaybe<TIdx> ParseIdx(TVMState& st) {
+ static_assert(IsPowerOf2(TIdx::ValueCount));
+ static const auto bits = GetCountWidth(TIdx::ValueCount);
+
+ TIdx idx;
+ if (!st.Input.Read(idx.Idx, bits)) {
+ return Nothing();
+ }
+ return idx;
+ }
+
+ namespace {
+ bool DoParsePos(TVMState& st, TPos& pos) {
+ static const auto bits = GetCountWidth(TPos::ValueCount);
+ const ui32 sz = st.Memory.size();
+
+ ui32 neg = -1;
+ Y_TRY_READ_BITS_BOOL(st, neg, 1);
+
+ ui32 delta = -1;
+ Y_TRY_READ_BITS_BOOL(st, delta, bits);
+
+ if (neg) {
+ if (st.Pos < delta) {
+ return false;
+ }
+ pos.Pos = st.Pos - delta;
+ } else {
+ if (st.Pos + delta >= sz) {
+ return false;
+ }
+ pos.Pos = st.Pos + delta;
+ }
+
+ return true;
+ }
+
+ template <class T>
+ bool DoParseType(TVMState& state, T& res) {
+ static const auto bits = GetCountWidth(T::TypeCount);
+
+ ui32 type = -1;
+ if (state.Input.Read(type, bits) && type < T::TypeCount) {
+ res.Type = (typename T::EType)(type);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ TMaybe<TPos> ParsePos(TVMState& state) {
+ TPos res;
+ if (DoParsePos(state, res)) {
+ return res;
+ }
+ return Nothing();
+ }
+
+ TMaybe<TRef> ParseRef(TVMState& state) {
+ TRef ref;
+ if (!DoParseType(state, ref)) {
+ return Nothing();
+ }
+
+ switch (ref.Type) {
+ case TRef::T_REF__POS:
+ if (!DoParsePos(state, ref)) {
+ return Nothing();
+ }
+ [[fallthrough]];
+ case TRef::T_CREATE_FRONT:
+ case TRef::T_CREATE_BACK:
+ return ref;
+ default:
+ Y_FAIL();
+ }
+ }
+
+ TMaybe<TSrc> ParseSrc(TVMState& state) {
+ TSrc src;
+ if (!DoParseType(state, src)) {
+ return Nothing();
+ }
+
+ switch (src.Type) {
+ case TSrc::T_LREF__POS:
+ case TSrc::T_CREF__POS:
+ case TSrc::T_RREF__POS:
+ if (!DoParsePos(state, src)) {
+ return Nothing();
+ }
+ return src;
+ default:
+ Y_FAIL();
+ }
+ }
+
+ TMaybe<TDst> ParseDst(TVMState& state) {
+ TDst dst;
+ if (!DoParseType(state, dst)) {
+ return Nothing();
+ }
+
+ switch (dst.Type) {
+ case TDst::T_LREF__POS:
+ case TDst::T_CREF__POS:
+ case TDst::T_RREF__POS:
+ if (!DoParsePos(state, dst)) {
+ return Nothing();
+ }
+ [[fallthrough]];
+ case TDst::T_CREATE_FRONT_LREF:
+ case TDst::T_CREATE_FRONT_CREF:
+ case TDst::T_CREATE_FRONT_RREF:
+ case TDst::T_CREATE_BACK_LREF:
+ case TDst::T_CREATE_BACK_CREF:
+ case TDst::T_CREATE_BACK_RREF:
+ return dst;
+ default:
+ Y_FAIL();
+ }
+ }
+
+ TMaybe<TPath> ParsePath(TVMState& state) {
+ static const ui32 bits = GetCountWidth(TPath::MaxLength);
+ TPath path;
+
+ ui32 len = -1;
+ Y_TRY_READ_BITS_MAYBE(state, len, bits);
+ while (len--) {
+ ui8 c;
+ Y_TRY_READ_BITS_MAYBE(state, c, 8);
+ path.Path.push_back(c);
+ }
+ return path;
+ }
+
+ TMaybe<TVMAction> ParseNextAction(TVMState& state) {
+ TVMAction res;
+
+ if (!DoParseType(state, res)) {
+ return Nothing();
+ }
+
+ switch (res.Type) {
+ case VMA_CREATE_BACK:
+ case VMA_CREATE_FRONT:
+ case VMA_DESTROY_BACK:
+ case VMA_DESTROY_FRONT:
+
+ case VMA_SET_DICT:
+ case VMA_SET_ARRAY:
+ case VMA_SET_NULL:
+ case VMA_GET_JSON:
+
+ case VMA_ARRAY_CLEAR:
+ case VMA_ARRAY_PUSH:
+ case VMA_DICT_CLEAR:
+ return res;
+
+ case VMA_JMP__POS:
+ case VMA_MERGE_UPDATE__POS:
+ case VMA_MERGE_REVERSE__POS:
+ case VMA_MERGE_COPY_FROM__POS:
+ case VMA_SWAP__POS:
+ if (res.SetArg(ParsePos(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_ARRAY_POP__REF:
+ if (res.SetArg(ParseRef(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_SET_STRING__IDX:
+ case VMA_SET_INT_NUMBER__IDX:
+ case VMA_ARRAY_INSERT__IDX:
+ case VMA_ARRAY_GET_OR_ADD__IDX:
+ case VMA_DICT_GET_OR_ADD__IDX:
+ if (res.SetArg(ParseIdx(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_CREATE_BACK__SRC:
+ case VMA_CREATE_FRONT__SRC:
+ case VMA_ASSIGN__SRC:
+ case VMA_ARRAY_PUSH__SRC:
+ if (res.SetArg(ParseSrc(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_ARRAY_PUSH__DST:
+ if (res.SetArg(ParseDst(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_ARRAY_DELETE__IDX_REF:
+ case VMA_ARRAY_GET__IDX_REF:
+ case VMA_ARRAY_GET_NO_ADD__IDX_REF:
+ case VMA_DICT_DELETE__IDX_REF:
+ case VMA_DICT_GET__IDX_REF:
+ case VMA_DICT_GET_NO_ADD__IDX_REF:
+ if (res.SetArg(ParseIdx(state)) && res.SetArg(ParseRef(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_ARRAY_INSERT__IDX_SRC:
+ case VMA_ARRAY_GET_OR_ADD__IDX_SRC:
+ case VMA_DICT_GET_OR_ADD__IDX_SRC:
+ if (res.SetArg(ParseIdx(state)) && res.SetArg(ParseSrc(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_ARRAY_INSERT__IDX_DST:
+ case VMA_ARRAY_GET_OR_ADD__IDX_DST:
+ case VMA_DICT_GET_OR_ADD__IDX_DST:
+ if (res.SetArg(ParseIdx(state)) && res.SetArg(ParseDst(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_EQUAL__POS_POS:
+ if (res.SetArg(ParsePos(state)) && res.SetArg(ParsePos(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ case VMA_SELECT_NO_ADD__PATH_REF:
+ case VMA_SELECT_OR_ADD__PATH_REF:
+ case VMA_SELECT_AND_DELETE__PATH_REF:
+ if (res.SetArg(ParsePath(state)) && res.SetArg(ParseRef(state))) {
+ return res;
+ } else {
+ return Nothing();
+ }
+
+ default:
+ return Nothing();
+ }
+ }
+}