Monkey-fixing a named function that immediately called
A script I am loading badly. He got this structure:
function bad_function() {
...
}
/* randomly generated stuff */
bad_function();
How can I change the behavior bad_function
if called immediately at the end of the script? I thought about creating a read-only property on window
before loading the script, but this throws an exception TypeError: Identifier 'bad_function' has already been declared
when the above script is executed:
Object.defineProperty(window, 'bad_function', {
value: function() {
/* my monkey-patched code */
}
});
How can I disable this function?
source to share
While this doesn't answer my question in general, I was able to render my specific function harmless by fixing a global type function encodeURIComponent
that was called inside my function, making the necessary changes, and throwing an exception to prevent the rest of the original function.
var old_encodeURIComponent = window.encodeURIComponent;
window.encodeURIComponent = function() {
// If this function is used in multiple places, look for variables in
// the current scope to determine if this is the right spot to start
// monkey patching.
if (typeof a === 'undefined' || typeof b === 'undefined') {
return old_encodeURIComponent.apply(this, arguments);
}
// You now have access to the variables in the scope of your target
// function. If your monkey patching is just a simple tweak, you're all set
// Otherwise, do what you need to do and throw an exception to stop the
// rest of the code from running
throw 'goodbye';
};
source to share
It's not nice, but all I can do is load the script via ajax instead of putting it in a tag <script>
, manipulate the resulting string to call your own version of the function (or "rename" bad_function
so it doesn't override your version). then put this in a tag <script>
and add it to your page:
Example using jQuery for simplicity:
function good_function() {
alert("I am good");
}
$.ajax({
url: '/echo/html/',
type: 'POST',
data: {
html: "function bad_function() { alert('hahaha'); } bad_function();",
delay: 0
},
success: function(data) {
console.log(data);
// comment this line to see the original
data = data.replace('bad_function();', 'good_function();')
var newScript = $('<script type="text/javascript" />').text(data);
$('body').append(newScript);
}
});
source to share