summaryrefslogtreecommitdiff
path: root/jstests/core/depth_limit.js
blob: 4e40c11436900a20575db722ef5d1ba4bcb5a434 (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
// SERVER-11781 Don't crash when converting deeply nested or cyclical JS objects to BSON.

function test() {
    function assertTooBig(obj) {
        // This used to crash rather than throwing an exception.
        assert.throws(function() {
            Object.bsonsize(obj);
        });
    }

    function assertNotTooBig(obj) {
        assert.doesNotThrow(function() {
            Object.bsonsize(obj);
        });
    }

    function objWithDepth(depth) {
        var out = 1;
        while (depth--) {
            out = {o: out};
        }
        return out;
    }

    function arrayWithDepth(depth) {
        var out = 1;
        while (depth--) {
            out = [out];
        }
        return out;
    }

    assertNotTooBig({});
    assertNotTooBig({array: []});

    var objCycle = {};
    objCycle.cycle = objCycle;
    assertTooBig(objCycle);

    var arrayCycle = [];
    arrayCycle.push(arrayCycle);
    assertTooBig({array: arrayCycle});

    var objDepthLimit = 150;
    assertNotTooBig(objWithDepth(objDepthLimit - 1));
    assertTooBig(objWithDepth(objDepthLimit));

    var arrayDepthLimit = objDepthLimit - 1;  // one lower due to wrapping object
    assertNotTooBig({array: arrayWithDepth(arrayDepthLimit - 1)});
    assertTooBig({array: arrayWithDepth(arrayDepthLimit)});
}

// test in shell
test();

// test on server
db.depth_limit.drop();
db.depth_limit.insert({});
db.depth_limit.find({$where: test}).itcount();  // itcount ensures that cursor is executed on server