source: node_modules/yaml/dist/nodes/Alias.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 3.3 KB
Line 
1'use strict';
2
3var anchors = require('../doc/anchors.js');
4var visit = require('../visit.js');
5var identity = require('./identity.js');
6var Node = require('./Node.js');
7var toJS = require('./toJS.js');
8
9class Alias extends Node.NodeBase {
10 constructor(source) {
11 super(identity.ALIAS);
12 this.source = source;
13 Object.defineProperty(this, 'tag', {
14 set() {
15 throw new Error('Alias nodes cannot have tags');
16 }
17 });
18 }
19 /**
20 * Resolve the value of this alias within `doc`, finding the last
21 * instance of the `source` anchor before this node.
22 */
23 resolve(doc) {
24 let found = undefined;
25 visit.visit(doc, {
26 Node: (_key, node) => {
27 if (node === this)
28 return visit.visit.BREAK;
29 if (node.anchor === this.source)
30 found = node;
31 }
32 });
33 return found;
34 }
35 toJSON(_arg, ctx) {
36 if (!ctx)
37 return { source: this.source };
38 const { anchors, doc, maxAliasCount } = ctx;
39 const source = this.resolve(doc);
40 if (!source) {
41 const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
42 throw new ReferenceError(msg);
43 }
44 let data = anchors.get(source);
45 if (!data) {
46 // Resolve anchors for Node.prototype.toJS()
47 toJS.toJS(source, null, ctx);
48 data = anchors.get(source);
49 }
50 /* istanbul ignore if */
51 if (!data || data.res === undefined) {
52 const msg = 'This should not happen: Alias anchor was not resolved?';
53 throw new ReferenceError(msg);
54 }
55 if (maxAliasCount >= 0) {
56 data.count += 1;
57 if (data.aliasCount === 0)
58 data.aliasCount = getAliasCount(doc, source, anchors);
59 if (data.count * data.aliasCount > maxAliasCount) {
60 const msg = 'Excessive alias count indicates a resource exhaustion attack';
61 throw new ReferenceError(msg);
62 }
63 }
64 return data.res;
65 }
66 toString(ctx, _onComment, _onChompKeep) {
67 const src = `*${this.source}`;
68 if (ctx) {
69 anchors.anchorIsValid(this.source);
70 if (ctx.options.verifyAliasOrder && !ctx.anchors.has(this.source)) {
71 const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
72 throw new Error(msg);
73 }
74 if (ctx.implicitKey)
75 return `${src} `;
76 }
77 return src;
78 }
79}
80function getAliasCount(doc, node, anchors) {
81 if (identity.isAlias(node)) {
82 const source = node.resolve(doc);
83 const anchor = anchors && source && anchors.get(source);
84 return anchor ? anchor.count * anchor.aliasCount : 0;
85 }
86 else if (identity.isCollection(node)) {
87 let count = 0;
88 for (const item of node.items) {
89 const c = getAliasCount(doc, item, anchors);
90 if (c > count)
91 count = c;
92 }
93 return count;
94 }
95 else if (identity.isPair(node)) {
96 const kc = getAliasCount(doc, node.key, anchors);
97 const vc = getAliasCount(doc, node.value, anchors);
98 return Math.max(kc, vc);
99 }
100 return 1;
101}
102
103exports.Alias = Alias;
Note: See TracBrowser for help on using the repository browser.