mirror of
https://forge.fsky.io/oneflux/omegafox.git
synced 2026-02-10 06:32:05 -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
|
||||
wget-log
|
||||
*.kate-swp
|
||||
*.log
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -140,11 +140,13 @@ package-windows:
|
|||
--fonts macos linux
|
||||
|
||||
run-launcher:
|
||||
rm -rf $(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch;
|
||||
make build-launcher arch=x86_64 os=linux;
|
||||
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
|
||||
|
||||
run-pw:
|
||||
rm -rf $(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/launch;
|
||||
make build-launcher arch=x86_64 os=linux;
|
||||
python3 scripts/run-pw.py \
|
||||
--version $(version) \
|
||||
|
|
|
|||
|
|
@ -571,6 +571,8 @@ class PageTarget {
|
|||
// default viewport.
|
||||
|
||||
// Do not allow default viewport size if Camoufox set it first
|
||||
const viewportSize = this._viewportSize || this._browserContext.defaultViewportSize;
|
||||
|
||||
if (
|
||||
!viewportSize &&
|
||||
this._browserContext.defaultViewportSize && (
|
||||
|
|
@ -582,7 +584,6 @@ class PageTarget {
|
|||
return;
|
||||
}
|
||||
|
||||
const viewportSize = this._viewportSize || this._browserContext.defaultViewportSize;
|
||||
if (viewportSize) {
|
||||
const {width, height} = viewportSize;
|
||||
this._linkedBrowser.style.setProperty('width', width + 'px');
|
||||
|
|
|
|||
|
|
@ -131,15 +131,20 @@ class Juggler {
|
|||
},
|
||||
};
|
||||
pipe.init(connection);
|
||||
ChromeUtils.camouDebug('Juggler pipe initialized');
|
||||
const dispatcher = new Dispatcher(connection);
|
||||
ChromeUtils.camouDebug('Dispatcher created');
|
||||
browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, browserStartupFinishedPromise, () => {
|
||||
ChromeUtils.camouDebug('BrowserHandler cleanup callback called');
|
||||
if (this._silent)
|
||||
Services.startup.exitLastWindowClosingSurvivalArea();
|
||||
connection.onclose();
|
||||
pipe.stop();
|
||||
pipeStopped = true;
|
||||
});
|
||||
ChromeUtils.camouDebug('BrowserHandler created');
|
||||
dispatcher.rootSession().setHandler(browserHandler);
|
||||
ChromeUtils.camouDebug('BrowserHandler set as root session handler');
|
||||
loadStyleSheet();
|
||||
dump(`\nJuggler listening to the pipe\n`);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -564,15 +564,11 @@ class Frame {
|
|||
webSocketService.removeListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
|
||||
this._webSocketListenerInnerWindowId = this.domWindow().windowGlobalChild.innerWindowId;
|
||||
webSocketService.addListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
|
||||
// Camoufox: Causes leaks.
|
||||
// for (const context of this._worldNameToContext.values())
|
||||
// this._runtime.destroyExecutionContext(context);
|
||||
// this._worldNameToContext.clear();
|
||||
|
||||
// this._worldNameToContext.set('', this._runtime.createExecutionContext(this.domWindow(), this.domWindow(), {
|
||||
// frameId: this._frameId,
|
||||
// name: '',
|
||||
// }));
|
||||
for (const context of this._worldNameToContext.values())
|
||||
this._runtime.destroyExecutionContext(context);
|
||||
this._worldNameToContext.clear();
|
||||
// Camoufox: Scope the initial execution context to prevent leaks
|
||||
this._createIsolatedContext('');
|
||||
for (const [name, world] of this._frameTree._isolatedWorlds) {
|
||||
if (name)
|
||||
this._createIsolatedContext(name);
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ class Runtime {
|
|||
emitEvent(this.events.onRuntimeError, {
|
||||
executionContext,
|
||||
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 = 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 {
|
||||
/**
|
||||
|
|
@ -44,6 +46,11 @@ class Dispatcher {
|
|||
|
||||
async _dispatch(event) {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
if (ChromeUtils.isCamouDebug())
|
||||
ChromeUtils.camouDebug(`[${new Date().toLocaleString()}]`
|
||||
+ `\nReceived message: ${safeJsonStringify(data)}`);
|
||||
|
||||
const id = data.id;
|
||||
const sessionId = data.sessionId;
|
||||
delete data.sessionId;
|
||||
|
|
@ -86,6 +93,13 @@ class Dispatcher {
|
|||
|
||||
_emitEvent(sessionId, eventName, params) {
|
||||
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;
|
||||
if (!scheme)
|
||||
throw new Error(`ERROR: event '${eventName}' is not supported`);
|
||||
|
|
@ -136,3 +150,44 @@ class ProtocolSession {
|
|||
this.EXPORTED_SYMBOLS = ['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
|
||||
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
|
||||
var debugPortInt int
|
||||
if len(addonsList) > 0 {
|
||||
|
|
@ -130,8 +130,18 @@ func runCamoufox(execName string, args []string, addonsList []string) {
|
|||
done <- true
|
||||
}()
|
||||
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)
|
||||
done <- true
|
||||
}()
|
||||
|
||||
<-done
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ func main() {
|
|||
configPath := parseArgs("--config", "{}", &args, true)
|
||||
addons := parseArgs("--addons", "[]", &args, true)
|
||||
excludeAddons := parseArgs("--exclude-addons", "[]", &args, true)
|
||||
stderrPath := parseArgs("--stderr", "", &args, true)
|
||||
|
||||
//*** PARSE CONFIG ***//
|
||||
|
||||
|
|
@ -26,6 +27,11 @@ func main() {
|
|||
parseJson(configPath, &configMap)
|
||||
validateConfig(configMap)
|
||||
|
||||
// Add "debug: True" to the config
|
||||
if stderrPath != "" {
|
||||
configMap["debug"] = true
|
||||
}
|
||||
|
||||
//*** PARSE ADDONS ***//
|
||||
|
||||
// If addons are passed, handle them
|
||||
|
|
@ -58,7 +64,7 @@ func main() {
|
|||
fmt.Printf("Error setting executable permissions: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
runCamoufox(execName, args, addonsList)
|
||||
runCamoufox(execName, args, addonsList, stderrPath)
|
||||
}
|
||||
|
||||
// Returns the absolute path relative to the launcher
|
||||
|
|
@ -93,13 +99,20 @@ func parseArgs(param string, defaultValue string, args *[]string, removeFromArgs
|
|||
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
|
||||
func parseJson(argv string, target interface{}) {
|
||||
// Unmarshal the config input into a map
|
||||
var data []byte
|
||||
var err error
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
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!)
|
||||
pref("fission.autostart", true);
|
||||
pref("fission.webContentIsolationStrategy", 2);
|
||||
|
||||
// Use dark theme by default
|
||||
pref("ui.systemUsesDarkTheme", 1);
|
||||
|
|
@ -450,7 +451,7 @@ pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
|
|||
pref("network.auth.use_redirect_for_retries", false);
|
||||
|
||||
// Disable cross-process iframes, but not cross-process navigations.
|
||||
pref("fission.webContentIsolationStrategy", 0);
|
||||
// pref("fission.webContentIsolationStrategy", 0);
|
||||
|
||||
// Disable BFCache in parent process.
|
||||
// We also separately disable BFCache in content via docSchell property.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
version=130.0
|
||||
release=beta.4
|
||||
release=beta.5
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue