From 6bc21b531e6d4d5166d0be04acff37a2849e4a34 Mon Sep 17 00:00:00 2001 From: Marnix Bouhuis Date: Fri, 15 Oct 2021 00:15:20 +0200 Subject: [PATCH] Update the way we get the global object, to comply with CSP no-unsafe-eval (#8864) --- src/google/protobuf/compiler/js/js_generator.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index cfd0e037c90..5542256f388 100644 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -3625,7 +3625,16 @@ void Generator::GenerateFile(const GeneratorOptions& options, if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { printer->Print("var proto = {};\n\n"); } else { - printer->Print("var global = Function('return this')();\n\n"); + // To get the global object we call a function with .call(null), this will set "this" inside the + // function to the global object. + // This does not work if we are running in strict mode ("use strict"), + // so we fallback to the following things (in order from first to last): + // - window: defined in browsers + // - global: defined in most server side environments like NodeJS + // - self: defined inside Web Workers (WorkerGlobalScope) + // - Function('return this')(): this will work on most platforms, but it may be blocked by things like CSP. + // Function('') is almost the same as eval('') + printer->Print("var global = (function() { return this || window || global || self || Function('return this')(); }).call(null);\n\n"); } for (int i = 0; i < file->dependency_count(); i++) {