File: safe_methods.js

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (118 lines) | stat: -rw-r--r-- 2,791 bytes parent folder | download | duplicates (3)
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
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This module keeps references to original methods before user code is able
// to overwrite them. We assume that this module is executed before any user
// code. The idea is similar to the extension system's SafeBuiltins, and since
// it's similar, we also use a $ prefix as a naming convention.
// For example,
// myElement.setAttribute(name, value);
// becomes
// $Element.setAttribute(myElement, name, value);
// We also provide access to getters and setters:
// myNode.parentNode;
// becomes
// $Node.parentNode.get(myNode);

function makeCallable(prototypeMethod) {
  return (thisArg, ...args) => {
    return $Function.apply(prototypeMethod, thisArg, args);
  };
}

function saveMethods(original, safe, methods) {
  safe.self = original;
  for (var method of methods) {
    safe[method] = makeCallable(original.prototype[method]);
  }
}

function saveAccessors(original, safe, properties) {
  for (var property of properties) {
    var desc = $Object.getOwnPropertyDescriptor(original.prototype, property);

    safe[property] = {
      get: desc.get && makeCallable(desc.get),
      set: desc.set && makeCallable(desc.set),
    };
  }
}

var SafeMethods = {
  $CustomElementRegistry: {},
  $Document: {},
  $Element: {},
  $EventTarget: {},
  $HTMLElement: {},
  $HTMLIFrameElement: {},
  $Headers: {},
  $MutationObserver: MutationObserver,
  $Node: {},
  $getComputedStyle: window.getComputedStyle,
  $parseInt: window.parseInt,
};

saveMethods(CustomElementRegistry, SafeMethods.$CustomElementRegistry, [
  'define',
]);

saveMethods(Document, SafeMethods.$Document, [
  'createElement',
  'webkitCancelFullScreen',
]);

saveAccessors(Document, SafeMethods.$Document, [
  'defaultView',
]);

saveMethods(Element, SafeMethods.$Element, [
  'attachShadow',
  'getAttribute',
  'getBoundingClientRect',
  'hasAttribute',
  'removeAttribute',
  'setAttribute',
  'webkitRequestFullScreen',
]);

saveMethods(EventTarget, SafeMethods.$EventTarget, [
  'addEventListener',
  'dispatchEvent',
  'removeEventListener',
]);

saveMethods(HTMLElement, SafeMethods.$HTMLElement, [
  'focus',
]);

saveAccessors(HTMLElement, SafeMethods.$HTMLElement, [
  'style',
  'innerText',
]);

saveMethods(Headers, SafeMethods.$Headers, [
  'append',
  'forEach',
]);

saveAccessors(HTMLIFrameElement, SafeMethods.$HTMLIFrameElement, [
  'contentWindow',
]);

saveMethods(MutationObserver, SafeMethods.$MutationObserver, [
  'observe',
  'takeRecords',
]);

saveMethods(Node, SafeMethods.$Node, [
  'appendChild',
  'replaceChild',
]);

saveAccessors(Node, SafeMethods.$Node, [
  'parentNode',
  'ownerDocument',
]);

exports.$set('SafeMethods', SafeMethods);