mirror of
https://forge.fsky.io/oneflux/omegafox.git
synced 2026-02-10 14:42:03 -08:00
- Add back frame execution contexts. Fixes leaks by using an isolated context. #3 #6 - Fixed other small errors in Juggler (viewport size & error message stack) - Add debugging functionality to Juggler - Add launcher argument to write stderr to a log file - Bumped to v130.0-beta.5
This commit is contained in:
parent
ea84f792df
commit
021b2f895d
12 changed files with 164 additions and 17 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -14,3 +14,4 @@ __pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
wget-log
|
wget-log
|
||||||
*.kate-swp
|
*.kate-swp
|
||||||
|
*.log
|
||||||
|
|
|
||||||
2
Makefile
2
Makefile
|
|
@ -140,11 +140,13 @@ package-windows:
|
||||||
--fonts macos linux
|
--fonts macos linux
|
||||||
|
|
||||||
run-launcher:
|
run-launcher:
|
||||||
|
rm -rf $(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch;
|
||||||
make build-launcher arch=x86_64 os=linux;
|
make build-launcher arch=x86_64 os=linux;
|
||||||
cp launcher/dist/launch $(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch;
|
cp launcher/dist/launch $(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch;
|
||||||
$(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch
|
$(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch
|
||||||
|
|
||||||
run-pw:
|
run-pw:
|
||||||
|
rm -rf $(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch;
|
||||||
make build-launcher arch=x86_64 os=linux;
|
make build-launcher arch=x86_64 os=linux;
|
||||||
python3 scripts/run-pw.py \
|
python3 scripts/run-pw.py \
|
||||||
--version $(version) \
|
--version $(version) \
|
||||||
|
|
|
||||||
|
|
@ -571,6 +571,8 @@ class PageTarget {
|
||||||
// default viewport.
|
// default viewport.
|
||||||
|
|
||||||
// Do not allow default viewport size if Camoufox set it first
|
// Do not allow default viewport size if Camoufox set it first
|
||||||
|
const viewportSize = this._viewportSize || this._browserContext.defaultViewportSize;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!viewportSize &&
|
!viewportSize &&
|
||||||
this._browserContext.defaultViewportSize && (
|
this._browserContext.defaultViewportSize && (
|
||||||
|
|
@ -582,7 +584,6 @@ class PageTarget {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const viewportSize = this._viewportSize || this._browserContext.defaultViewportSize;
|
|
||||||
if (viewportSize) {
|
if (viewportSize) {
|
||||||
const {width, height} = viewportSize;
|
const {width, height} = viewportSize;
|
||||||
this._linkedBrowser.style.setProperty('width', width + 'px');
|
this._linkedBrowser.style.setProperty('width', width + 'px');
|
||||||
|
|
|
||||||
|
|
@ -131,15 +131,20 @@ class Juggler {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
pipe.init(connection);
|
pipe.init(connection);
|
||||||
|
ChromeUtils.camouDebug('Juggler pipe initialized');
|
||||||
const dispatcher = new Dispatcher(connection);
|
const dispatcher = new Dispatcher(connection);
|
||||||
|
ChromeUtils.camouDebug('Dispatcher created');
|
||||||
browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, browserStartupFinishedPromise, () => {
|
browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, browserStartupFinishedPromise, () => {
|
||||||
|
ChromeUtils.camouDebug('BrowserHandler cleanup callback called');
|
||||||
if (this._silent)
|
if (this._silent)
|
||||||
Services.startup.exitLastWindowClosingSurvivalArea();
|
Services.startup.exitLastWindowClosingSurvivalArea();
|
||||||
connection.onclose();
|
connection.onclose();
|
||||||
pipe.stop();
|
pipe.stop();
|
||||||
pipeStopped = true;
|
pipeStopped = true;
|
||||||
});
|
});
|
||||||
|
ChromeUtils.camouDebug('BrowserHandler created');
|
||||||
dispatcher.rootSession().setHandler(browserHandler);
|
dispatcher.rootSession().setHandler(browserHandler);
|
||||||
|
ChromeUtils.camouDebug('BrowserHandler set as root session handler');
|
||||||
loadStyleSheet();
|
loadStyleSheet();
|
||||||
dump(`\nJuggler listening to the pipe\n`);
|
dump(`\nJuggler listening to the pipe\n`);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -564,15 +564,11 @@ class Frame {
|
||||||
webSocketService.removeListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
|
webSocketService.removeListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
|
||||||
this._webSocketListenerInnerWindowId = this.domWindow().windowGlobalChild.innerWindowId;
|
this._webSocketListenerInnerWindowId = this.domWindow().windowGlobalChild.innerWindowId;
|
||||||
webSocketService.addListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
|
webSocketService.addListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
|
||||||
// Camoufox: Causes leaks.
|
for (const context of this._worldNameToContext.values())
|
||||||
// for (const context of this._worldNameToContext.values())
|
this._runtime.destroyExecutionContext(context);
|
||||||
// this._runtime.destroyExecutionContext(context);
|
this._worldNameToContext.clear();
|
||||||
// this._worldNameToContext.clear();
|
// Camoufox: Scope the initial execution context to prevent leaks
|
||||||
|
this._createIsolatedContext('');
|
||||||
// this._worldNameToContext.set('', this._runtime.createExecutionContext(this.domWindow(), this.domWindow(), {
|
|
||||||
// frameId: this._frameId,
|
|
||||||
// name: '',
|
|
||||||
// }));
|
|
||||||
for (const [name, world] of this._frameTree._isolatedWorlds) {
|
for (const [name, world] of this._frameTree._isolatedWorlds) {
|
||||||
if (name)
|
if (name)
|
||||||
this._createIsolatedContext(name);
|
this._createIsolatedContext(name);
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ class Runtime {
|
||||||
emitEvent(this.events.onRuntimeError, {
|
emitEvent(this.events.onRuntimeError, {
|
||||||
executionContext,
|
executionContext,
|
||||||
message: message.errorMessage,
|
message: message.errorMessage,
|
||||||
stack: message.stack.toString(),
|
stack: message.stack?.toString() || '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ const {protocol, checkScheme} = ChromeUtils.import("chrome://juggler/content/pro
|
||||||
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||||
|
|
||||||
const helper = new Helper();
|
const helper = new Helper();
|
||||||
|
// Camoufox: Exclude redundant internal events from logs.
|
||||||
|
const EXCLUDED_DBG = ['Page.navigationStarted', 'Page.frameAttached', 'Runtime.executionContextCreated', 'Runtime.console', 'Page.navigationAborted', 'Page.eventFired'];
|
||||||
|
|
||||||
class Dispatcher {
|
class Dispatcher {
|
||||||
/**
|
/**
|
||||||
|
|
@ -44,6 +46,11 @@ class Dispatcher {
|
||||||
|
|
||||||
async _dispatch(event) {
|
async _dispatch(event) {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
|
|
||||||
|
if (ChromeUtils.isCamouDebug())
|
||||||
|
ChromeUtils.camouDebug(`[${new Date().toLocaleString()}]`
|
||||||
|
+ `\nReceived message: ${safeJsonStringify(data)}`);
|
||||||
|
|
||||||
const id = data.id;
|
const id = data.id;
|
||||||
const sessionId = data.sessionId;
|
const sessionId = data.sessionId;
|
||||||
delete data.sessionId;
|
delete data.sessionId;
|
||||||
|
|
@ -86,6 +93,13 @@ class Dispatcher {
|
||||||
|
|
||||||
_emitEvent(sessionId, eventName, params) {
|
_emitEvent(sessionId, eventName, params) {
|
||||||
const [domain, eName] = eventName.split('.');
|
const [domain, eName] = eventName.split('.');
|
||||||
|
|
||||||
|
// Camoufox: Log internal events
|
||||||
|
if (ChromeUtils.isCamouDebug() && !EXCLUDED_DBG.includes(eventName) && domain !== 'Network') {
|
||||||
|
ChromeUtils.camouDebug(`[${new Date().toLocaleString()}]`
|
||||||
|
+ `\nInternal event: ${eventName}\nParams: ${JSON.stringify(params, null, 2)}`);
|
||||||
|
}
|
||||||
|
|
||||||
const scheme = protocol.domains[domain] ? protocol.domains[domain].events[eName] : null;
|
const scheme = protocol.domains[domain] ? protocol.domains[domain].events[eName] : null;
|
||||||
if (!scheme)
|
if (!scheme)
|
||||||
throw new Error(`ERROR: event '${eventName}' is not supported`);
|
throw new Error(`ERROR: event '${eventName}' is not supported`);
|
||||||
|
|
@ -136,3 +150,44 @@ class ProtocolSession {
|
||||||
this.EXPORTED_SYMBOLS = ['Dispatcher'];
|
this.EXPORTED_SYMBOLS = ['Dispatcher'];
|
||||||
this.Dispatcher = Dispatcher;
|
this.Dispatcher = Dispatcher;
|
||||||
|
|
||||||
|
|
||||||
|
function formatDate(date) {
|
||||||
|
const pad = (num) => String(num).padStart(2, '0');
|
||||||
|
return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function truncateObject(obj, maxDepth = 8, maxLength = 100) {
|
||||||
|
if (maxDepth < 0) return '[Max Depth Reached]';
|
||||||
|
|
||||||
|
if (typeof obj !== 'object' || obj === null) {
|
||||||
|
return typeof obj === 'string' ? truncateString(obj, maxLength) : obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
return obj.slice(0, 10).map(item => truncateObject(item, maxDepth - 1, maxLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
const truncated = {};
|
||||||
|
for (const [key, value] of Object.entries(obj)) {
|
||||||
|
if (Object.keys(truncated).length >= 10) {
|
||||||
|
truncated['...'] = '[Truncated]';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
truncated[key] = truncateObject(value, maxDepth - 1, maxLength);
|
||||||
|
}
|
||||||
|
return truncated;
|
||||||
|
}
|
||||||
|
|
||||||
|
function truncateString(str, maxLength) {
|
||||||
|
if (str.length <= maxLength) return str;
|
||||||
|
ChromeUtils.camouDebug(`String length: ${str.length}`);
|
||||||
|
return str.substr(0, maxLength) + '... [truncated]';
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeJsonStringify(data) {
|
||||||
|
try {
|
||||||
|
return JSON.stringify(truncateObject(data), null, 2);
|
||||||
|
} catch (error) {
|
||||||
|
return `[Unable to stringify: ${error.message}]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ func filterOutput(r io.Reader, w io.Writer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run Camoufox
|
// Run Camoufox
|
||||||
func runCamoufox(execName string, args []string, addonsList []string) {
|
func runCamoufox(execName string, args []string, addonsList []string, stderrPath string) {
|
||||||
// If addons are specified, get the debug port
|
// If addons are specified, get the debug port
|
||||||
var debugPortInt int
|
var debugPortInt int
|
||||||
if len(addonsList) > 0 {
|
if len(addonsList) > 0 {
|
||||||
|
|
@ -130,8 +130,18 @@ func runCamoufox(execName string, args []string, addonsList []string) {
|
||||||
done <- true
|
done <- true
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
|
// If stderrPath is not empty, write to the file
|
||||||
|
fmt.Printf("Setting stderr to file: %s\n", stderrPath)
|
||||||
|
if stderrPath != "" {
|
||||||
|
file, err := os.Create(stderrPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error creating stderr file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
filterOutput(stderr, file)
|
||||||
|
}
|
||||||
filterOutput(stderr, os.Stderr)
|
filterOutput(stderr, os.Stderr)
|
||||||
done <- true
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
<-done
|
<-done
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ func main() {
|
||||||
configPath := parseArgs("--config", "{}", &args, true)
|
configPath := parseArgs("--config", "{}", &args, true)
|
||||||
addons := parseArgs("--addons", "[]", &args, true)
|
addons := parseArgs("--addons", "[]", &args, true)
|
||||||
excludeAddons := parseArgs("--exclude-addons", "[]", &args, true)
|
excludeAddons := parseArgs("--exclude-addons", "[]", &args, true)
|
||||||
|
stderrPath := parseArgs("--stderr", "", &args, true)
|
||||||
|
|
||||||
//*** PARSE CONFIG ***//
|
//*** PARSE CONFIG ***//
|
||||||
|
|
||||||
|
|
@ -26,6 +27,11 @@ func main() {
|
||||||
parseJson(configPath, &configMap)
|
parseJson(configPath, &configMap)
|
||||||
validateConfig(configMap)
|
validateConfig(configMap)
|
||||||
|
|
||||||
|
// Add "debug: True" to the config
|
||||||
|
if stderrPath != "" {
|
||||||
|
configMap["debug"] = true
|
||||||
|
}
|
||||||
|
|
||||||
//*** PARSE ADDONS ***//
|
//*** PARSE ADDONS ***//
|
||||||
|
|
||||||
// If addons are passed, handle them
|
// If addons are passed, handle them
|
||||||
|
|
@ -58,7 +64,7 @@ func main() {
|
||||||
fmt.Printf("Error setting executable permissions: %v\n", err)
|
fmt.Printf("Error setting executable permissions: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
runCamoufox(execName, args, addonsList)
|
runCamoufox(execName, args, addonsList, stderrPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the absolute path relative to the launcher
|
// Returns the absolute path relative to the launcher
|
||||||
|
|
@ -93,13 +99,20 @@ func parseArgs(param string, defaultValue string, args *[]string, removeFromArgs
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fileExists checks if a file exists
|
||||||
|
func fileExists(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
// Parses a JSON string or file into a map
|
// Parses a JSON string or file into a map
|
||||||
func parseJson(argv string, target interface{}) {
|
func parseJson(argv string, target interface{}) {
|
||||||
// Unmarshal the config input into a map
|
// Unmarshal the config input into a map
|
||||||
var data []byte
|
var data []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
// Check if the input is a file path or inline JSON
|
// Check if the input is a file path or inline JSON
|
||||||
if _, err := os.Stat(argv); err == nil {
|
if fileExists(argv) {
|
||||||
data, err = os.ReadFile(argv)
|
data, err = os.ReadFile(argv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error reading config file: %v\n", err)
|
fmt.Printf("Error reading config file: %v\n", err)
|
||||||
|
|
|
||||||
63
patches/debug.patch
Normal file
63
patches/debug.patch
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
diff --git a/dom/base/ChromeUtils.cpp b/dom/base/ChromeUtils.cpp
|
||||||
|
index 71d897a0d0..2234834f3e 100644
|
||||||
|
--- a/dom/base/ChromeUtils.cpp
|
||||||
|
+++ b/dom/base/ChromeUtils.cpp
|
||||||
|
@@ -2069,6 +2069,25 @@ bool ChromeUtils::IsDarkBackground(GlobalObject&, Element& aElement) {
|
||||||
|
return nsNativeTheme::IsDarkBackground(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* static */
|
||||||
|
+void ChromeUtils::CamouDebug(GlobalObject& aGlobal,
|
||||||
|
+ const nsAString& aVarName) {
|
||||||
|
+ if (auto value = MaskConfig::GetBool("debug");
|
||||||
|
+ value.has_value() && !value.value()) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ NS_ConvertUTF16toUTF8 utf8VarName(aVarName);
|
||||||
|
+ printf_stderr("DEBUG: %s\n", utf8VarName.get());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool ChromeUtils::IsCamouDebug(GlobalObject& aGlobal) {
|
||||||
|
+ if (auto value = MaskConfig::GetBool("debug");
|
||||||
|
+ value.has_value() && value.value()) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
double ChromeUtils::DateNow(GlobalObject&) { return JS_Now() / 1000.0; }
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
diff --git a/dom/base/ChromeUtils.h b/dom/base/ChromeUtils.h
|
||||||
|
index 42b74131d6..9f151ca2e7 100644
|
||||||
|
--- a/dom/base/ChromeUtils.h
|
||||||
|
+++ b/dom/base/ChromeUtils.h
|
||||||
|
@@ -301,6 +301,10 @@ class ChromeUtils {
|
||||||
|
|
||||||
|
static bool IsDarkBackground(GlobalObject&, Element&);
|
||||||
|
|
||||||
|
+ static void CamouDebug(GlobalObject& aGlobal, const nsAString& aVarName);
|
||||||
|
+
|
||||||
|
+ static bool IsCamouDebug(GlobalObject& aGlobal);
|
||||||
|
+
|
||||||
|
static double DateNow(GlobalObject&);
|
||||||
|
|
||||||
|
static void EnsureJSOracleStarted(GlobalObject&);
|
||||||
|
diff --git a/dom/chrome-webidl/ChromeUtils.webidl b/dom/chrome-webidl/ChromeUtils.webidl
|
||||||
|
index f761be86a4..c6409bd56e 100644
|
||||||
|
--- a/dom/chrome-webidl/ChromeUtils.webidl
|
||||||
|
+++ b/dom/chrome-webidl/ChromeUtils.webidl
|
||||||
|
@@ -746,6 +746,13 @@ partial namespace ChromeUtils {
|
||||||
|
*/
|
||||||
|
boolean isDarkBackground(Element element);
|
||||||
|
|
||||||
|
+ /**
|
||||||
|
+ * Camoufox debug commands
|
||||||
|
+ */
|
||||||
|
+ undefined camouDebug(DOMString varName);
|
||||||
|
+
|
||||||
|
+ boolean isCamouDebug();
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Starts the JSOracle process for ORB JavaScript validation, if it hasn't started already.
|
||||||
|
*/
|
||||||
|
|
@ -19,6 +19,7 @@ pref("media.peerconnection.ice.no_host", true);
|
||||||
|
|
||||||
// Force enable content isolation (WAFs can detect this!)
|
// Force enable content isolation (WAFs can detect this!)
|
||||||
pref("fission.autostart", true);
|
pref("fission.autostart", true);
|
||||||
|
pref("fission.webContentIsolationStrategy", 2);
|
||||||
|
|
||||||
// Use dark theme by default
|
// Use dark theme by default
|
||||||
pref("ui.systemUsesDarkTheme", 1);
|
pref("ui.systemUsesDarkTheme", 1);
|
||||||
|
|
@ -450,7 +451,7 @@ pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
|
||||||
pref("network.auth.use_redirect_for_retries", false);
|
pref("network.auth.use_redirect_for_retries", false);
|
||||||
|
|
||||||
// Disable cross-process iframes, but not cross-process navigations.
|
// Disable cross-process iframes, but not cross-process navigations.
|
||||||
pref("fission.webContentIsolationStrategy", 0);
|
// pref("fission.webContentIsolationStrategy", 0);
|
||||||
|
|
||||||
// Disable BFCache in parent process.
|
// Disable BFCache in parent process.
|
||||||
// We also separately disable BFCache in content via docSchell property.
|
// We also separately disable BFCache in content via docSchell property.
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
version=130.0
|
version=130.0
|
||||||
release=beta.4
|
release=beta.5
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue