File disable-fuses.patch of Package nodejs-electron
Upstream allows some customization of runtime behavior by performing binary witchcraft on the Electron executable.
This cannot work with a systemwide electron, and any program depending on features gated behind a fuse would need additional patching anyway.
This patch removes fuse switches from the binary and makes the makes the compiler able to optimize away any dependant code which is now dead.
--- src/electron/build/fuses/build.py.orig 2024-03-27 16:05:03.002778083 +0100
+++ src/electron/build/fuses/build.py 2024-03-27 20:08:44.765543587 +0100
@@ -7,7 +7,9 @@ import sys
dir_path = os.path.dirname(os.path.realpath(__file__))
-SENTINEL = "dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX"
+# If your build process tries to patch the electron binary, it's going to break anyway with system electron.
+# Changing the magic number to ensure that the build fails instead of getting problems later in runtime.
+SENTINEL = "Unavailable with system electron"
TEMPLATE_H = """
#ifndef ELECTRON_FUSES_H_
@@ -21,7 +23,7 @@ TEMPLATE_H = """
namespace electron::fuses {
-extern const volatile char kFuseWire[];
+constexpr char kFuseWire[] = { /* sentinel */ {sentinel}, /* fuse_version */ {fuse_version}, /* fuse_wire_length */ {fuse_wire_length}, /* fuse_wire */ {initial_config}};
{getters}
@@ -42,8 +44,6 @@ TEMPLATE_CC = """
namespace electron::fuses {
-const volatile char kFuseWire[] = { /* sentinel */ {sentinel}, /* fuse_version */ {fuse_version}, /* fuse_wire_length */ {fuse_wire_length}, /* fuse_wire */ {initial_config}};
-
{getters}
} // namespace electron:fuses
@@ -70,23 +70,18 @@ for fuse in fuses:
index += 1
initial_config += fuse_defaults[fuse]
name = ''.join(word.title() for word in fuse.split('_'))
- getters_h += "FUSE_EXPORT bool Is{name}Enabled();\n".replace("{name}", name)
- getters_cc += """
-bool Is{name}Enabled() {
-#if DCHECK_IS_ON()
- // RunAsNode is checked so early that base::CommandLine isn't yet
- // initialized, so guard here to avoid a CHECK.
- if (base::CommandLine::InitializedForCurrentProcess()) {
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch("{switch_name}")) {
- std::string switch_value = command_line->GetSwitchValueASCII("{switch_name}");
- return switch_value == "1";
- }
- }
-#endif
+ getters_h += """
+constexpr bool INLINE_Is{name}Enabled() {
return kFuseWire[{index}] == '1';
}
-""".replace("{name}", name).replace("{switch_name}", f"set-fuse-{fuse.lower()}").replace("{index}", str(index))
+#define Is{name}Enabled INLINE_Is{name}Enabled
+""".replace("{name}", name).replace("{index}", str(index))
+ getters_cc += """
+#undef Is{name}Enabled
+FUSE_EXPORT bool Is{name}Enabled() {
+ return INLINE_Is{name}Enabled();
+}
+""".replace("{name}", name)
def c_hex(n):
s = hex(n)[2:]
@@ -98,12 +93,13 @@ def hex_arr(s):
arr.append(c_hex(ord(char)))
return ",".join(arr)
-header = TEMPLATE_H.replace("{getters}", getters_h.strip())
-impl = TEMPLATE_CC.replace("{sentinel}", hex_arr(SENTINEL))
-impl = impl.replace("{fuse_version}", c_hex(fuse_version))
-impl = impl.replace("{fuse_wire_length}", c_hex(len(fuses)))
-impl = impl.replace("{initial_config}", hex_arr(initial_config))
-impl = impl.replace("{getters}", getters_cc.strip())
+header = TEMPLATE_H.replace("{sentinel}", hex_arr(SENTINEL))
+header = header.replace("{fuse_version}", c_hex(fuse_version))
+header = header.replace("{fuse_wire_length}", c_hex(len(fuses)))
+header = header.replace("{initial_config}", hex_arr(initial_config))
+header = header.replace("{getters}", getters_h.strip())
+
+impl = TEMPLATE_CC.replace("{getters}", getters_cc.strip())
with open(sys.argv[1], 'w') as f:
f.write(header)