Эти linemarkers упомянуты в man gcc
для опции -P
.
Опция -P
предназначена специально для того, чтобы избавиться от этих строк для ясности:
gcc -E -P source.c
Запустите код в iframe
, размещенном на другом Origin. Это единственный способ гарантировать, что ненадежный код изолирован и не доступен для доступа к глобальным или DOM страницы.
Насколько мне известно, в Javascript любая переменная, объявленная вне функции, принадлежит глобальной области видимости и поэтому доступна из любого места вашего кода.
Каждая функция имеет свою собственную область действия, и любая переменная, объявленная внутри этой функции, доступна только из этой функции и любых вложенных функций. Локальная область в JavaScript создается только функциями, которая также называется функцией scope.
Помещение функции внутри другой функции может быть одной из возможностей, когда вы можете достичь уменьшенной области видимости (т.е. вложенной области)
Вы не можете ограничить область действия с помощью методов «вызов» или «применить», но вы можете использовать простой трюк, используя «eval» и scoping, чтобы скрыть какие-либо конкретные глобальные переменные от вызываемой функции .
Причина этого в том, что функция имеет доступ к «глобальным» переменным, которые объявлены в области, которую сама функция объявляет. Таким образом, скопировав код метода и введя его в eval, вы можете существенно изменить глобальную область функции, которую вы хотите вызвать. Конечный результат по существу заключается в том, что он может несколько изолировать фрагмент кода javascript.
Вот пример полного кода:
<html>
<head>
<title>This is the page title.</title>
<script>
function displayTitle()
{
alert(document.title);
}
function callMethod(method)
{
var code = "" +
// replace global "window" in the scope of the eval
"var window = {};" +
// replace global "document" in the scope of the eval
"var document = {}; " +
"(" +
// inject the Function you want to call into the eval
method.toString() +
// call the injected method
")();" +
"";
eval(code);
}
callMethod(displayTitle);
</script>
</head>
<body></body>
</html>
Код, который получает eval'd, выглядит следующим образом:
var window = {};
var document = {};
(function displayTitle()
{
alert(document.title);
})();
this.document.title
.
– josh3736
26 January 2012 в 17:51
EDIT: этот ответ не скрывает переменные window.something. Но у него есть чистый способ запуска пользовательского кода. Я пытаюсь найти способ маскировать переменные окна
Вы можете использовать функцию javascript Function.prototype.bind () , чтобы привязать функцию, представленную пользователем к настраиваемой переменной области видимости по вашему выбору, в этой настраиваемой области вы можете выбрать, какие переменные должны делиться с пользовательской функцией и скрывать. Для пользовательских функций код сможет получить доступ к переменным, которые вы использовали, используя this.variableName. Вот пример, чтобы подробно остановиться на идее:
// A couple of global variable that we will use to test the idea
var sharedGlobal = "I am shared";
var notSharedGlobal = "But I will not be shared";
function submit() {
// Another two function scoped variables that we will also use to test
var sharedFuncScope = "I am in function scope and shared";
var notSharedFuncScope = "I am in function scope but I am not shared";
// The custom scope object, in here you can choose which variables to share with the custom function
var funcScope = {
sharedGlobal: sharedGlobal,
sharedFuncScope: sharedFuncScope
};
// Read the custom function body
var customFnText = document.getElementById("customfn").value;
// create a new function object using the Function constructor, and bind it to our custom-made scope object
var func = new Function(customFnText).bind(funcScope);
// execute the function, and print the output to the page.
document.getElementById("output").innerHTML = JSON.stringify(func());
}
// sample test function body, this will test which of the shared variables does the custom function has access to.
/*
return {
sharedGlobal : this.sharedGlobal || null,
sharedFuncScope : this.sharedFuncScope || null,
notSharedGlobal : this.notSharedGlobal || null,
notSharedFuncScope : this.notSharedFuncScope || null
};
*/
<script type="text/javascript" src="app.js"></script>
<h1>Add your custom body here</h1>
<textarea id="customfn"></textarea>
<br>
<button onclick="submit()">Submit</button>
<br>
<div id="output"></div>
В следующем примере:
Использование встроенных веб-рабочих может позволить запускать безопасные функции. Что-то вроде этого позволяет пользователю вводить javascript, запускать его и получать результат без доступа к вашему глобальному контексту.
globalVariable = "I'm global";
document.getElementById('submit').onclick = function() {
createWorker();
}
function createWorker() {
// The text in the textarea is the function you want to run
var fnText = document.getElementById('fnText').value;
// You wrap the function to add a postMessage
// with the function result
var workerTemplate = "\
function userDefined(){" + fnText +
"}\
postMessage(userDefined());\
onmessage = function(e){console.log(e);\
}"
// web workers are normally js files, but using blobs
// you can create them with strings.
var blob = new Blob([workerTemplate], {
type: "text/javascript"
});
var wk = new Worker(window.URL.createObjectURL(blob));
wk.onmessage = function(e) {
// you listen for the return.
console.log('Function result:', e.data);
}
}
<div>Enter a javascript function and click submit</div>
<textarea id="fnText"></textarea>
<button id="submit">
Run the function
</button>
Вы можете попробовать их, например, вставив их в текстовое поле:
return "I'm a safe function";
Вы можете видеть, что это безопасно:
return globalVariable;
У вас даже могут быть более сложные скрипты, например:
var a = 4, b = 5;
function insideFn(){
// here c is global, but only in the worker context
c = a + b;
}
insideFn();
return c;
См. Информацию о веб-мастерах здесь, особенно встроенных веб-работников: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Embedded_workers
Вы можете использовать WebWorkers для выделения вашего кода:
Создать полностью отдельную и параллельную среду исполнения (то есть отдельный поток или процесс или эквивалентную конструкцию) и выполните остальные эти шаги асинхронно в этом контексте.
blockquote>Вот простой пример:
someGlobal = 5; //As a worker normally take another JavaScript file to execute we convert the function in an URL: http://stackoverflow.com/a/16799132/2576706 function getScriptPath(foo) { return window.URL.createObjectURL(new Blob([foo], { type: 'text/javascript' })); } function protectCode(code) { var worker = new Worker(getScriptPath(code)); } protectCode('console.log(someGlobal)'); // prints 10 protectCode('console.log(this.someGlobal)'); protectCode('console.log(eval("someGlobal"))'); protectCode('console.log(window.someGlobal)');
Этот код вернет:
Uncaught ReferenceError: someGlobal is not defined
undefined
Uncaught ReferenceError: someGlobal is not defined
и
Uncaught ReferenceError: window is not defined
, поэтому код теперь безопасен.
Я дам технический ответ на ваш вопрос, по крайней мере, с одной возможностью. Используйте имя глобального в качестве аргумента для этой функции:
someGlobal = 5;
function cantSeeThatGlobal(someGlobal) {
console.log(someGlobal);
}
cantSeeThatGlobal(); // prints undefined
cantSeeThatGlobal(10); // prints 10
Лучше, конечно, просто не использовать глобальные переменные когда-либо.
this.someGlobal
или window.someGlobal
или eval('someGlobal')
– josh3736
26 January 2012 в 17:14
Создайте локальную переменную с тем же именем. Если у вас есть глобальная переменная:
var globalvar;
В вашей функции:
function noGlobal(); {
var globalvar;
}
Если функция ссылается на globalvar, она будет ссылаться на локальную.
window.globalvar
.
– Jamie
3 April 2016 в 07:32
Немного поздно, но, возможно, это поможет вам немного
function RestrictFunction(params) {
params = ( params == undefined ? {} : params );
var scope = ( params.scope == undefined ? window : params.scope );
var data = ( params.data == undefined ? {} : params.data );
var script = ( params.script == undefined ? '' : params.script );
if (typeof params.script == 'function') {
script = params.script.toString();
script = script.substring(script.indexOf("{") + 1, script.lastIndexOf("}"));
}
// example: override native functions that on the white list
var setTimeout = function(_function,_interval) {
// this is important to prevent the user using `this` in the function and access the DOM
var interval = scope.setTimeout( function() {
RestrictFunction({
scope:scope,
data:data,
script:_function
});
} , _interval );
// Auto clear long user intervals
scope.setTimeout( function() {
scope.clearTimeout(interval);
} , 60*1000 );
return interval;
}
// example: create custom functions
var trace = function(str) {
scope.console.log(str);
}
return (function() {
// remove functions, objects and variables from scope
var queue = [];
var WhiteList = [
"Blob","Boolean","Date","String","Number","Object","Array","Text","Function",
"unescape","escape","encodeURI","encodeURIComponent","parseFloat","parseInt",
"isNaN","isFinite","undefined","NaN",
"JSON","Math","RegExp",
"clearTimeout","setTimeout"
];
var properties = Object.getOwnPropertyNames(scope);
for (var k = 0; k<properties.length; k++ ) {
if (WhiteList.indexOf(properties[k])!=-1) continue;
queue.push("var "+properties[k]+" = undefined;");
}
for (var k in scope) {
if (WhiteList.indexOf(k)!=-1) continue;
queue.push("var "+k+" = undefined;");
}
queue.push("var WhiteList = undefined;");
queue.push("var params = undefined;") ;
queue.push("var scope = undefined;") ;
queue.push("var data = undefined;") ;
queue.push("var k = undefined;");
queue.push("var properties = undefined;");
queue.push("var queue = undefined;");
queue.push("var script = undefined;");
queue.push(script);
try {
return eval( '(function(){'+ queue.join("\n") +'}).apply(data);' );
} catch(err) { }
}).apply(data);
}
Пример использования
// dummy to test if we can access the DOM
var dummy = function() {
this.notify = function(msg) {
console.log( msg );
};
}
var result = RestrictFunction({
// Custom data to pass to the user script , Accessible via `this`
data:{
prop1: 'hello world',
prop2: ["hello","world"],
prop3: new dummy()
},
// User custom script as string or function
script:function() {
trace( this );
this.msg = "hello world";
this.prop3.notify(this.msg);
setTimeout( function() {
trace(this);
} , 10 );
trace( data );
trace( params );
trace( scope );
trace( window );
trace( XMLHttpRequest );
trace( eval );
return "done!"; // not required to return value...
},
});
console.log( "result:" , result );