VM: различия между версиями

Материал из support.qbpro.ru
imported>Supportadmin
Нет описания правки
imported>Supportadmin
 
(не показано 15 промежуточных версий этого же участника)
Строка 3: Строка 3:
'''2 - Unstable'''
'''2 - Unstable'''


В Node.js, JavaScript код может быть скомпилирован и сразу выполнен или скомпилирован, а запущен позже или скомпилирован, сохранен и еще позже запущен :). Для этого неоходимо включить в код require('vm');.
В Node.js, JavaScript код может быть скомпилирован и сразу выполнен или скомпилирован, а запущен позже или скомпилирован, сохранен и еще позже запущен :). Для этого неоходимо включить в код  
<nowiki>require('vm');</nowiki>.


'''Внимание'''
'''Внимание'''
Строка 11: Строка 12:
'''Sandboxes'''
'''Sandboxes'''


Аргумент sandbox в vm.runInNewContext и vm.createContext , наряду с аргументом initSandbox в vm.createContext, ведут себя не так, как можно было ожидать, и обычно их поведение варьируется между различными версиями Node.
Аргумент sandbox в vm.runInNewContext и vm.createContext , наряду с аргументом initSandbox в vm.createContext, могут вести себя не так, как можно было ожидать, и обычно их поведение варьируется между различными версиями Node.


The key issue to be aware of is that V8 provides no way to directly control the global object used within a context. As a result, while properties of your sandbox object will be available in the context, any properties from the prototypes of the sandbox may not be available. Furthermore, the this expression within the global scope of the context evaluates to the empty object ({}) instead of to your sandbox.
Ключевой момент заключается в том, что V8 не предоставляет возможности непосредственно контролировать глобальный объект, используемый в контексте. В результате, в то время как свойства вашего объекта -песочницы будут доступны в контексте, любые свойства из прототипов песочницы могут быть недоступны. Кроме того, это выражение в глобальной области видимости контекста вычисляется в пустой объект ({}), а не к изолированной среды.


Your sandbox's properties are also not shared directly with the script. Instead, the properties of the sandbox are copied into the context at the beginning of execution, and then after execution, the properties are copied back out in an attempt to propagate any changes.
Свойства изолированной среды в также не разделяют непосредственно со сценарием. Вместо этого свойства песочнице копируются в контексте в начале исполнения, а затем после выполнения, свойства копируются обратно в попытке распространяются любые изменения.


'''Globals'''
'''Globals'''


Properties of the global object, like Array and String, have different values inside of a context. This means that common expressions like [] instanceof Array or Object.getPrototypeOf([]) === Array.prototype may not produce expected results when used inside of scripts evaluated via the vm module.
Свойства глобального объекта, такие как Array и String имеют различные значения внутри контекста. Это значит, что такое выражение  как  [] относящееся к  Array или Object.getPrototypeOf([]) === Array.prototype может дать неожиданный результат при выполнении  внутри модуля vm.


Some of these problems have known workarounds listed in the issues for vm on GitHub. for example, Array.isArray works around the example problem with Array.
Some of these problems have known workarounds listed in the issues for vm on GitHub. for example, Array.isArray works around the example problem with Array.
Строка 28: Строка 29:
vm.runInThisContext()  компилирует код, запускает его и возвращает результат. Запущенный код не имеет доступа к локальной области видимости переменных (local scope). filename необязательный параметр, и используется только при трассировке (stack traces).
vm.runInThisContext()  компилирует код, запускает его и возвращает результат. Запущенный код не имеет доступа к локальной области видимости переменных (local scope). filename необязательный параметр, и используется только при трассировке (stack traces).


Example of using vm.runInThisContext and eval to run the same code:
Пример ипользования vm.runInThisContext и eval для запуска кода:


  <nowiki>var localVar = 123,
  <nowiki>var localVar = 123,
Строка 45: Строка 46:
// localVar: 1, evaled: 1</nowiki>
// localVar: 1, evaled: 1</nowiki>


Прим. переводчика: Метод eval возвращает значение последнего вычисленного выражения.


===vm.runInNewContext(code, [sandbox], [filename])===
===vm.runInNewContext(code, [sandbox], [filename])===


vm.runInNewContext compiles code, then runs it in sandbox and returns the result. Running code does not have access to local scope. The object sandbox will be used as the global object for code. sandbox and filename are optional, filename is only used in stack traces.
vm.runInNewContext() компилирует код, а затем запускает его в sandbox и возвращает результат. Запущенный код не имеет доступа к локальной области видимости переменных (local scope). Объект sandbox используется как глобальный объект (global object) для кода. sandbox и filename необязательные параметры, и filename используется только при трассировке (stack traces).


Example: compile and execute code that increments a global variable and sets a new one. These globals are contained in the sandbox.
Example: compile and execute code that increments a global variable and sets a new one. These globals are contained in the sandbox.
Строка 67: Строка 70:
In case of syntax error in code, vm.runInNewContext emits the syntax error to stderr and throws an exception.
In case of syntax error in code, vm.runInNewContext emits the syntax error to stderr and throws an exception.


==vm.runInContext(code, context, [filename])==
vm.runInContext компилирует код, а затем запускает его в контексте и возвращает результат.(V8) контекст включает глобальный объект, вместе с набором встроенных объектов и функций. Выполнение кода не имеет доступа к локальной области видимости и глобальный объект проводится в контексте будет использоваться в качестве глобального объекта для кода. filename не является обязательным, он используется только в трассировки стека.
Пример: компиляция и выполнение кода в созданном контексте.
<nowiki>var util = require('util'),
    vm = require('vm'),
    initSandbox = {
      animal: 'cat',
      count: 2
    },
    context = vm.createContext(initSandbox);
vm.runInContext('count += 1; name = "CATT"', context, 'myfile.vm');
console.log(util.inspect(context));
// { animal: 'cat', count: 3, name: 'CATT' }</nowiki>
Следует отметить, что CreateContext выполнит мелкий клон предоставленным объектом песочнице, чтобы инициализировать глобальный объект в недавно построенной контексте.
Обратите внимание, что работает ненадежного кода является непростым делом, требующих большую заботу. Для предотвращения случайного глобальной переменной утечки, vm.runInContext весьма полезно, но благополучно работает ненадежного кода требует отдельного процесса.
В случае синтаксической ошибки в коде, vm.runInContext излучает синтаксической ошибке в стандартный поток ошибок и генерирует исключение.
==vm.createContext([initSandbox])==
vm.createContext() создает новый контекст который используется в качестве второго аргумента при последующем вызове в vm.runInContext(). A (V8) context comprises a global object together with a set of build-in objects and functions. The optional argument initSandbox will be shallow-copied to seed the initial contents of the global object used by the context.
==vm.createScript(code, [filename])==
createScrip компилирует код, но не выполняет его. Наоборот, он возвращает объект vm.Script содержащий этот скомпилированный код. Этот скрипт может быть запущен намного позже использую другие методы VM. The returned script is not bound to any global object. It is bound before each run, just for that run. filename is optional, it's only used in stack traces.
В случае синтаксической ошибки в коде, createScript напечатает ошибку в stderr и вызовет exception(исключение).


==Class: Script==
A class for running scripts. Returned by vm.createScript.


==script.runInThisContext()==
Так же как в vm.runInThisContext, но метод прекомпилирует объект Script. script.runInThisContext выполняет код script и возвращает результат. Запущенный код не имеет доступа к локальной области видидимости переменных (local scope), но имеет доступ к глобальному объекту (global object) (v8: in actual context).


Пример использования script.runInThisContext для компиляции кода и многократного его запуска:


<nowiki>var vm = require('vm');


globalVar = 0;


var script = vm.createScript('globalVar += 1', 'myfile.vm');


for (var i = 0; i < 1000 ; i += 1) {
  script.runInThisContext();
}


console.log(globalVar);


// 1000</nowiki>


==script.runInNewContext([sandbox])==
Подобно vm.runInNewContext, метод предварительно скомпилированного объекта Script, script.runInNewContext, запускает код скрипта с песочницей, в качестве глобального объекта и возвращает результат. Выполнение кода не имеет доступа к локальной области видимости. Песочница не является обязательной.


=== Методы ===
Пример: компилировать код, который увеличивает глобальную переменную и устанавливает один, затем выполнить этот код несколько раз. Эти глобальные содержатся в песочнице.
<nowiki>createContext([Object initSandbox]) -> Object</nowiki>
 
vm.createContext() '''''создает новый контекст''''' который используется в качестве второго аргумента при последующем вызове в vm.runInContext().
  <nowiki>var util = require('util'),
<nowiki>createScript(String code[, String filename]) -> vm.Script</nowiki>
    vm = require('vm'),
Этот скрипт может быть запущен намного позже использую другие методы VM. В случае синтаксической ошибки в коде,  createScript напечатает ошибку в stderr и вызовет exception(исключение).
    sandbox = {
  <nowiki>runInContext(String code, Object context[, String filename]) -> String</nowiki>
      animal: 'cat',
vm.runInContext() компилирует код, а затем запускает его в контексте и возвращает результат.
      count: 2
<nowiki>runInNewContext(String code[, Object sandbox][, String filename])</nowiki>
    };
vm.runInNewContext() компилирует код, а затем запускает его в sandbox и возвращает результат. Запущенный код не имеет доступа к локальной области видимости переменных (local scope). Объект sandbox используется как глобальный объект (global object) для кода. sandbox и filename необязательные параметры, и filename используется только при трассировке (stack traces).
 
<nowiki>runInThisContext(String code[, String filename]) -> String</nowiki>
var script = vm.createScript('count += 1; name = "kitty"', 'myfile.vm');
vm.runInThisContext() компилирует код, как если бы он был загружен из файла, запускает его и возвращает результат. Запущенный код не имеет доступа к локальной области видимости переменных (local scope). filename необязательный параметр, и используется только при трассировке (stack traces).


== vm.Script ==
for (var i = 0; i < 10 ; i += 1) {
  script.runInNewContext(sandbox);
}


Этот объект создается как результат матода vm.createScript(). Он представляет собой некоторый скомпилированный код, чем может быть запущен позже.
console.log(util.inspect(sandbox));


===Methods===
// { animal: 'cat', count: 12, name: 'kitty' }</nowiki>
<nowiki>runInNewContext([Object sandbox]) -> String</nowiki>
Note that running untrusted code is a tricky business requiring great care. To prevent accidental global variable leakage, script.runInNewContext is quite useful, but safely running untrusted code requires a separate process.
Аналогичен vm.runInNewContext(), этот метод прекомпилирует Script object.
<nowiki>runInThisContext() -> String</nowiki>
Аналогичен vm.runInThisContext(), но  метод прекомпилирует Script object.

Текущая версия от 14:24, 20 марта 2014

http://nodejs.org/api/vm.html

2 - Unstable

В Node.js, JavaScript код может быть скомпилирован и сразу выполнен или скомпилирован, а запущен позже или скомпилирован, сохранен и еще позже запущен :). Для этого неоходимо включить в код

require('vm');.

Внимание

The vm module has many known issues and edge cases. If you run into issues or unexpected behavior, please consult the open issues on GitHub. Some of the biggest problems are described below.

Sandboxes

Аргумент sandbox в vm.runInNewContext и vm.createContext , наряду с аргументом initSandbox в vm.createContext, могут вести себя не так, как можно было ожидать, и обычно их поведение варьируется между различными версиями Node.

Ключевой момент заключается в том, что V8 не предоставляет возможности непосредственно контролировать глобальный объект, используемый в контексте. В результате, в то время как свойства вашего объекта -песочницы будут доступны в контексте, любые свойства из прототипов песочницы могут быть недоступны. Кроме того, это выражение в глобальной области видимости контекста вычисляется в пустой объект ({}), а не к изолированной среды.

Свойства изолированной среды в также не разделяют непосредственно со сценарием. Вместо этого свойства песочнице копируются в контексте в начале исполнения, а затем после выполнения, свойства копируются обратно в попытке распространяются любые изменения.

Globals

Свойства глобального объекта, такие как Array и String имеют различные значения внутри контекста. Это значит, что такое выражение как [] относящееся к Array или Object.getPrototypeOf([]) === Array.prototype может дать неожиданный результат при выполнении внутри модуля vm.

Some of these problems have known workarounds listed in the issues for vm on GitHub. for example, Array.isArray works around the example problem with Array.


vm.runInThisContext(code, [filename])

vm.runInThisContext() компилирует код, запускает его и возвращает результат. Запущенный код не имеет доступа к локальной области видимости переменных (local scope). filename необязательный параметр, и используется только при трассировке (stack traces).

Пример ипользования vm.runInThisContext и eval для запуска кода:

var localVar = 123,
    usingscript, evaled,
    vm = require('vm');

usingscript = vm.runInThisContext('localVar = 1;',
  'myfile.vm');
console.log('localVar: ' + localVar + ', usingscript: ' +
  usingscript);
evaled = eval('localVar = 1;');
console.log('localVar: ' + localVar + ', evaled: ' +
  evaled);

// localVar: 123, usingscript: 1
// localVar: 1, evaled: 1


Прим. переводчика: Метод eval возвращает значение последнего вычисленного выражения.

vm.runInNewContext(code, [sandbox], [filename])

vm.runInNewContext() компилирует код, а затем запускает его в sandbox и возвращает результат. Запущенный код не имеет доступа к локальной области видимости переменных (local scope). Объект sandbox используется как глобальный объект (global object) для кода. sandbox и filename необязательные параметры, и filename используется только при трассировке (stack traces).

Example: compile and execute code that increments a global variable and sets a new one. These globals are contained in the sandbox.

var util = require('util'),
    vm = require('vm'),
    sandbox = {
      animal: 'cat',
      count: 2
    };

vm.runInNewContext('count += 1; name = "kitty"', sandbox, 'myfile.vm');
console.log(util.inspect(sandbox));

// { animal: 'cat', count: 3, name: 'kitty' }

Note that running untrusted code is a tricky business requiring great care. To prevent accidental global variable leakage, vm.runInNewContext is quite useful, but safely running untrusted code requires a separate process.

In case of syntax error in code, vm.runInNewContext emits the syntax error to stderr and throws an exception.

vm.runInContext(code, context, [filename])

vm.runInContext компилирует код, а затем запускает его в контексте и возвращает результат.(V8) контекст включает глобальный объект, вместе с набором встроенных объектов и функций. Выполнение кода не имеет доступа к локальной области видимости и глобальный объект проводится в контексте будет использоваться в качестве глобального объекта для кода. filename не является обязательным, он используется только в трассировки стека.

Пример: компиляция и выполнение кода в созданном контексте.

var util = require('util'),
    vm = require('vm'),
    initSandbox = {
      animal: 'cat',
      count: 2
    },
    context = vm.createContext(initSandbox);

vm.runInContext('count += 1; name = "CATT"', context, 'myfile.vm');
console.log(util.inspect(context));

// { animal: 'cat', count: 3, name: 'CATT' }

Следует отметить, что CreateContext выполнит мелкий клон предоставленным объектом песочнице, чтобы инициализировать глобальный объект в недавно построенной контексте.

Обратите внимание, что работает ненадежного кода является непростым делом, требующих большую заботу. Для предотвращения случайного глобальной переменной утечки, vm.runInContext весьма полезно, но благополучно работает ненадежного кода требует отдельного процесса.

В случае синтаксической ошибки в коде, vm.runInContext излучает синтаксической ошибке в стандартный поток ошибок и генерирует исключение.

vm.createContext([initSandbox])

vm.createContext() создает новый контекст который используется в качестве второго аргумента при последующем вызове в vm.runInContext(). A (V8) context comprises a global object together with a set of build-in objects and functions. The optional argument initSandbox will be shallow-copied to seed the initial contents of the global object used by the context.

vm.createScript(code, [filename])

createScrip компилирует код, но не выполняет его. Наоборот, он возвращает объект vm.Script содержащий этот скомпилированный код. Этот скрипт может быть запущен намного позже использую другие методы VM. The returned script is not bound to any global object. It is bound before each run, just for that run. filename is optional, it's only used in stack traces.

В случае синтаксической ошибки в коде, createScript напечатает ошибку в stderr и вызовет exception(исключение).

Class: Script

A class for running scripts. Returned by vm.createScript.

script.runInThisContext()

Так же как в vm.runInThisContext, но метод прекомпилирует объект Script. script.runInThisContext выполняет код script и возвращает результат. Запущенный код не имеет доступа к локальной области видидимости переменных (local scope), но имеет доступ к глобальному объекту (global object) (v8: in actual context).

Пример использования script.runInThisContext для компиляции кода и многократного его запуска:

var vm = require('vm');

globalVar = 0;

var script = vm.createScript('globalVar += 1', 'myfile.vm');

for (var i = 0; i < 1000 ; i += 1) {
  script.runInThisContext();
}

console.log(globalVar);

// 1000

script.runInNewContext([sandbox])

Подобно vm.runInNewContext, метод предварительно скомпилированного объекта Script, script.runInNewContext, запускает код скрипта с песочницей, в качестве глобального объекта и возвращает результат. Выполнение кода не имеет доступа к локальной области видимости. Песочница не является обязательной.

Пример: компилировать код, который увеличивает глобальную переменную и устанавливает один, затем выполнить этот код несколько раз. Эти глобальные содержатся в песочнице.

var util = require('util'),
    vm = require('vm'),
    sandbox = {
      animal: 'cat',
      count: 2
    };

var script = vm.createScript('count += 1; name = "kitty"', 'myfile.vm');

for (var i = 0; i < 10 ; i += 1) {
  script.runInNewContext(sandbox);
}

console.log(util.inspect(sandbox));

// { animal: 'cat', count: 12, name: 'kitty' }

Note that running untrusted code is a tricky business requiring great care. To prevent accidental global variable leakage, script.runInNewContext is quite useful, but safely running untrusted code requires a separate process.