summaryrefslogtreecommitdiff
path: root/jstests/aggregation/expressions/regex_error_cases.js
blob: 6472c56112317d5bef32b7855b99f136609379f7 (plain)
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
// Test various error cases of $regexMatch, $regexFind and $regexFindAll aggregation expressions.
(function() {
'use strict';

load('jstests/libs/sbe_assert_error_override.js');   // Override error-code-checking APIs.
load('jstests/libs/aggregation_pipeline_utils.js');  // For executeAggregationTestCase().

const coll = db.regex_error_cases;
coll.drop();

function assertFails(parameters, errorCode, allowNullResponse = false) {
    // Check constant parameters.
    let inputDocument = {text: 'ABCD'};

    const constantParameters = Object.assign({input: '$text'}, parameters);
    const regexMatchTest =
        Object.assign({inputDocuments: inputDocument, expectedErrorCode: errorCode},
                      allowNullResponse ? {expectedResults: [{"result": false}]} : {});
    const regexFindTest =
        Object.assign({inputDocuments: inputDocument, expectedErrorCode: errorCode},
                      allowNullResponse ? {expectedResults: [{"result": null}]} : {});
    const regexFindAllTest =
        Object.assign({inputDocuments: inputDocument, expectedErrorCode: errorCode},
                      allowNullResponse ? {expectedResults: [{"result": []}]} : {});

    executeAggregationTestCase(
        coll,
        Object.assign(
            {pipeline: [{$project: {"_id": 0, result: {'$regexMatch': constantParameters}}}]},
            regexMatchTest));
    executeAggregationTestCase(
        coll,
        Object.assign(
            {pipeline: [{$project: {"_id": 0, result: {'$regexFind': constantParameters}}}]},
            regexFindTest));
    executeAggregationTestCase(
        coll,
        Object.assign(
            {pipeline: [{$project: {"_id": 0, result: {'$regexFindAll': constantParameters}}}]},
            regexFindAllTest));

    // Check constant parameters, but without optimization phase.
    try {
        assert.commandWorked(db.adminCommand(
            {'configureFailPoint': 'disablePipelineOptimization', 'mode': 'alwaysOn'}));

        executeAggregationTestCase(
            coll,
            Object.assign(
                {pipeline: [{$project: {"_id": 0, result: {'$regexMatch': constantParameters}}}]},
                regexMatchTest));
        executeAggregationTestCase(
            coll,
            Object.assign(
                {pipeline: [{$project: {"_id": 0, result: {'$regexFind': constantParameters}}}]},
                regexFindTest));
        executeAggregationTestCase(
            coll,
            Object.assign(
                {pipeline: [{$project: {"_id": 0, result: {'$regexFindAll': constantParameters}}}]},
                regexFindAllTest));
    } finally {
        assert.commandWorked(
            db.adminCommand({'configureFailPoint': 'disablePipelineOptimization', 'mode': 'off'}));
    }

    // Check parameters pulled from collection.
    inputDocument = Object.assign(inputDocument, parameters);

    const dynamicParameters = {input: '$text'};
    if ('regex' in parameters) {
        dynamicParameters.regex = '$regex';
    }
    if ('options' in parameters) {
        dynamicParameters.options = '$options';
    }
    executeAggregationTestCase(
        coll,
        Object.assign(
            {pipeline: [{$project: {"_id": 0, result: {'$regexMatch': dynamicParameters}}}]},
            regexMatchTest));
    executeAggregationTestCase(
        coll,
        Object.assign(
            {pipeline: [{$project: {"_id": 0, result: {'$regexFind': dynamicParameters}}}]},
            regexFindTest));
    executeAggregationTestCase(
        coll,
        Object.assign(
            {pipeline: [{$project: {"_id": 0, result: {'$regexFindAll': dynamicParameters}}}]},
            regexFindAllTest));
}

// Regex pattern must be string, BSON RegEx or null.
assertFails({regex: 123}, 51105);

// Regex flags must be string or null.
assertFails({regex: '.*', options: 123}, 51106);

// Options cannot be specified both in BSON RegEx and in options field.
assertFails({regex: /.*/i, options: 's'}, 51107);

// Regex pattern cannot contain null bytes.
assertFails({regex: '[a-b]+\0[c-d]+'}, 51109);

// Regex flags cannot contain null bytes.
assertFails({regex: '.*', options: 'i\0s'}, 51110);
// If regex pattern is null, the query could either return null or report the 'cannot contain null
// bytes' error.
assertFails({regex: null, options: 'i\0s'}, 51110, true /* allowNullResponse */);

// Regex pattern must be a valid regular expression.
assertFails({regex: '[a-'}, 51111);

// Regex flags must be valid.
assertFails({regex: '.*', options: 'ish'}, 51108);
}());