File: test_validator_with_custom_regular_expression_engine.cpp

package info (click to toggle)
valijson 1.0.3%2Brepack-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,756 kB
  • sloc: cpp: 19,769; sh: 134; makefile: 24
file content (125 lines) | stat: -rw-r--r-- 4,082 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifdef _MSC_VER
#pragma warning(disable: 4706)
#include <picojson.h>
#pragma warning(default: 4706)
#else
#include <picojson.h>
#endif

#include <iostream>

#include <gtest/gtest.h>

#include <valijson/adapters/jsoncpp_adapter.hpp>
#include <valijson/adapters/rapidjson_adapter.hpp>
#include <valijson/adapters/picojson_adapter.hpp>
#include <valijson/adapters/nlohmann_json_adapter.hpp>
#include <valijson/utils/jsoncpp_utils.hpp>
#include <valijson/utils/picojson_utils.hpp>
#include <valijson/utils/rapidjson_utils.hpp>
#include <valijson/utils/nlohmann_json_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validation_results.hpp>
#include <valijson/validator.hpp>
#include <valijson/exceptions.hpp>
#ifdef VALIJSON_BUILD_POCO_ADAPTER
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#endif

using valijson::adapters::AdapterTraits;
using valijson::adapters::RapidJsonAdapter;
using valijson::Schema;
using valijson::SchemaParser;
using valijson::Validator;

static void createFileFromContent(const std::string& filename, const std::string& content)
{
    std::ofstream outfile(filename, std::ofstream::out | std::ofstream::trunc);
    outfile << content << std::endl;
    outfile.close();
};

//Potentially :
// Define a struct CustomRegexEngine that handle both problem and use it as replacement of Validator.
//using CustomValidator = ValidatorT<CustomRegexEngine>;

TEST(valijson, valijson_be_robust_against_bad_regular_expression)
{
    GTEST_SKIP() << "Skipping: causes segmentation fault with default Validator";

    static const std::string schema = R"(
    {
        "properties": {
            "text": {
                "pattern": "^[\\s\\S]+$",
                "type": "string"
            }
        }
    }
    )";

    createFileFromContent("schema.json", schema);
    rapidjson::Document mySchemaDoc;
    ASSERT_TRUE(valijson::utils::loadDocument("schema.json", mySchemaDoc));

    Schema mySchema;
    SchemaParser parser;
    RapidJsonAdapter mySchemaAdapter(mySchemaDoc);
    parser.populateSchema(mySchemaAdapter, mySchema);
    rapidjson::Document myTargetDoc;

    std::string payload = "{ \"text\" :  \"";
    for (int i = 0; i< 100000; ++i) {
        payload += 'A';
    }
    payload += "\"}";

    createFileFromContent("payload.json", payload);

    ASSERT_TRUE(valijson::utils::loadDocument("payload.json", myTargetDoc));

    // This test crash (segfault) is validator is not customized with custom RegexpEngine
    Validator validator;
    RapidJsonAdapter myTargetAdapter(myTargetDoc);
    ASSERT_TRUE(validator.validate(mySchema, myTargetAdapter, nullptr));
}

TEST(valijson, valijson_be_robust_against_catastrophic_backtracking_regular_expression)
{
    GTEST_SKIP() << "Skipping: hangs due to non management of catastrophic backtracking with default Validator";

    static const std::string schema = R"(
    {
        "properties": {
            "text": {
                "pattern": "((A+)*)+$",
                "type": "string"
            }
        }
    }
    )";

    createFileFromContent("schema.json", schema);
    rapidjson::Document mySchemaDoc;
    ASSERT_TRUE(valijson::utils::loadDocument("schema.json", mySchemaDoc));

    Schema mySchema;
    SchemaParser parser;
    RapidJsonAdapter mySchemaAdapter(mySchemaDoc);
    parser.populateSchema(mySchemaAdapter, mySchema);
    rapidjson::Document myTargetDoc;

    std::string payload = "{ \"text\" :  \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC\"}";
    createFileFromContent("payload.json", payload);

    ASSERT_TRUE(valijson::utils::loadDocument("payload.json", myTargetDoc));

    //This test takes endless time if validator is not customized with custom RegexpEngine
    Validator validator;
    RapidJsonAdapter myTargetAdapter(myTargetDoc);

    //payload is correct regarding the regexp but evaluation is impossible due to catastrophic regexp bactracking. so we return false.
    ASSERT_FALSE(validator.validate(mySchema, myTargetAdapter, nullptr));
}