mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1881567 - Added Rust application to read and launch Firefox upon receiving native messages r=mhughes,nrishel,glandium,gsvelto
Differential Revision: https://phabricator.services.mozilla.com/D202467
This commit is contained in:
parent
502b94eb4e
commit
b3eba1dc18
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -4013,6 +4013,17 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nmhproxy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mozbuild",
|
||||
"mozilla-central-workspace-hack",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
|
@ -5,6 +5,7 @@
|
||||
# and do not need to be listed here. Their external dependencies are vendored
|
||||
# into `third_party/rust` by `mach vendor rust`.
|
||||
members = [
|
||||
"browser/app/nmhproxy/",
|
||||
"js/src/frontend/smoosh",
|
||||
"js/src/rust",
|
||||
"netwerk/test/http3server",
|
||||
|
@ -16,6 +16,7 @@
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
/minidump-analyzer
|
||||
#endif
|
||||
/nmhproxy
|
||||
/pingsender
|
||||
/pk12util
|
||||
/ssltunnel
|
||||
|
@ -135,6 +135,9 @@ if CONFIG["MOZ_SANDBOX"] and CONFIG["OS_ARCH"] == "WINNT":
|
||||
"usp10.dll",
|
||||
]
|
||||
|
||||
if CONFIG["TARGET_OS"] in ("WINNT", "OSX"):
|
||||
DIRS += ["nmhproxy"]
|
||||
|
||||
# Control the default heap size.
|
||||
# This is the heap returned by GetProcessHeap().
|
||||
# As we use the CRT heap, the default size is too large and wastes VM.
|
||||
|
17
browser/app/nmhproxy/Cargo.toml
Normal file
17
browser/app/nmhproxy/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "nmhproxy"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
description = "A lightweight native messaging listener executable for the Firefox Bridge extension which launches Firefox in regular or private modes, avoiding the need to convert Firefox itself into a listener."
|
||||
|
||||
[[bin]]
|
||||
name = "nmhproxy"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
mozbuild = "0.1"
|
||||
mozilla-central-workspace-hack = { version = "0.1", features = ["nmhproxy"], optional = true }
|
||||
serde = { version = "1", features = ["derive", "rc"] }
|
||||
serde_json = "1.0"
|
||||
url = "2.4"
|
15
browser/app/nmhproxy/moz.build
Normal file
15
browser/app/nmhproxy/moz.build
Normal file
@ -0,0 +1,15 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
RUST_PROGRAMS += [
|
||||
"nmhproxy",
|
||||
]
|
||||
|
||||
# Ideally, the build system would set @rpath to be @executable_path as
|
||||
# a default for this executable so that this addition to LDFLAGS would not be
|
||||
# needed here. Bug 1772575 is filed to implement that.
|
||||
if CONFIG["OS_ARCH"] == "Darwin":
|
||||
LDFLAGS += ["-Wl,-rpath,@executable_path"]
|
350
browser/app/nmhproxy/src/commands.rs
Normal file
350
browser/app/nmhproxy/src/commands.rs
Normal file
@ -0,0 +1,350 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::process::Command;
|
||||
use url::Url;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const OS_NAME: &str = "windows";
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
const OS_NAME: &str = "macos";
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(tag = "command", content = "data")]
|
||||
// {
|
||||
// "command": "LaunchFirefox",
|
||||
// "data": {"url": "https://example.com"},
|
||||
// }
|
||||
pub enum FirefoxCommand {
|
||||
LaunchFirefox { url: String },
|
||||
LaunchFirefoxPrivate { url: String },
|
||||
GetVersion {},
|
||||
}
|
||||
#[derive(Serialize, Deserialize)]
|
||||
// {
|
||||
// "message": "Successful launch",
|
||||
// "result_code": 1,
|
||||
// }
|
||||
pub struct Response {
|
||||
pub message: String,
|
||||
pub result_code: u32,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
pub enum ResultCode {
|
||||
Success = 0,
|
||||
Error = 1,
|
||||
}
|
||||
impl From<ResultCode> for u32 {
|
||||
fn from(m: ResultCode) -> u32 {
|
||||
m as u32
|
||||
}
|
||||
}
|
||||
|
||||
trait CommandRunner {
|
||||
fn new() -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
fn arg(&mut self, arg: &str) -> &mut Self;
|
||||
fn args(&mut self, args: &[&str]) -> &mut Self;
|
||||
fn spawn(&mut self) -> std::io::Result<()>;
|
||||
fn to_string(&mut self) -> std::io::Result<String>;
|
||||
}
|
||||
|
||||
impl CommandRunner for Command {
|
||||
fn new() -> Self {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
Command::new("open")
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use mozbuild::config::MOZ_APP_NAME;
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
// Get the current executable's path, we know Firefox is in the
|
||||
// same folder is nmhproxy.exe so we can use that.
|
||||
let nmh_exe_path = env::current_exe().unwrap();
|
||||
let nmh_exe_folder = nmh_exe_path.parent().unwrap_or_else(|| Path::new(""));
|
||||
let moz_exe_path = nmh_exe_folder.join(format!("{}.exe", MOZ_APP_NAME));
|
||||
Command::new(moz_exe_path)
|
||||
}
|
||||
}
|
||||
fn arg(&mut self, arg: &str) -> &mut Self {
|
||||
self.arg(arg)
|
||||
}
|
||||
fn args(&mut self, args: &[&str]) -> &mut Self {
|
||||
self.args(args)
|
||||
}
|
||||
fn spawn(&mut self) -> std::io::Result<()> {
|
||||
self.spawn().map(|_| ())
|
||||
}
|
||||
fn to_string(&mut self) -> std::io::Result<String> {
|
||||
Ok("".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
struct MockCommand {
|
||||
command_line: String,
|
||||
}
|
||||
|
||||
impl CommandRunner for MockCommand {
|
||||
fn new() -> Self {
|
||||
MockCommand {
|
||||
command_line: String::new(),
|
||||
}
|
||||
}
|
||||
fn arg(&mut self, arg: &str) -> &mut Self {
|
||||
self.command_line.push_str(arg);
|
||||
self.command_line.push(' ');
|
||||
self
|
||||
}
|
||||
fn args(&mut self, args: &[&str]) -> &mut Self {
|
||||
for arg in args {
|
||||
self.command_line.push_str(arg);
|
||||
self.command_line.push(' ');
|
||||
}
|
||||
self
|
||||
}
|
||||
fn spawn(&mut self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn to_string(&mut self) -> std::io::Result<String> {
|
||||
Ok(self.command_line.clone())
|
||||
}
|
||||
}
|
||||
|
||||
// The message length is a 32-bit integer in native byte order
|
||||
pub fn read_message_length<R: Read>(mut reader: R) -> std::io::Result<u32> {
|
||||
let mut buffer = [0u8; 4];
|
||||
reader.read_exact(&mut buffer)?;
|
||||
let length: u32 = u32::from_ne_bytes(buffer);
|
||||
if (length > 0) && (length < 100 * 1024) {
|
||||
Ok(length)
|
||||
} else {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Invalid message length",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_message_string<R: Read>(mut reader: R, length: u32) -> io::Result<String> {
|
||||
let mut buffer = vec![0u8; length.try_into().unwrap()];
|
||||
reader.read_exact(&mut buffer)?;
|
||||
let message =
|
||||
String::from_utf8(buffer).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
Ok(message)
|
||||
}
|
||||
|
||||
pub fn process_command(command: &FirefoxCommand) -> std::io::Result<bool> {
|
||||
match &command {
|
||||
FirefoxCommand::LaunchFirefox { url } => {
|
||||
launch_firefox::<Command>(url.to_owned(), false, OS_NAME)?;
|
||||
Ok(true)
|
||||
}
|
||||
FirefoxCommand::LaunchFirefoxPrivate { url } => {
|
||||
launch_firefox::<Command>(url.to_owned(), true, OS_NAME)?;
|
||||
Ok(true)
|
||||
}
|
||||
FirefoxCommand::GetVersion {} => generate_response("1", ResultCode::Success.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_response(message: &str, result_code: u32) -> std::io::Result<bool> {
|
||||
let response_struct = Response {
|
||||
message: message.to_string(),
|
||||
result_code,
|
||||
};
|
||||
let response_str = serde_json::to_string(&response_struct)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
|
||||
let response_len_bytes: [u8; 4] = (response_str.len() as u32).to_ne_bytes();
|
||||
std::io::stdout().write_all(&response_len_bytes)?;
|
||||
std::io::stdout().write_all(response_str.as_bytes())?;
|
||||
std::io::stdout().flush()?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn validate_url(url: String) -> std::io::Result<String> {
|
||||
let parsed_url = Url::parse(url.as_str())
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
|
||||
match parsed_url.scheme() {
|
||||
"http" | "https" | "file" => Ok(parsed_url.to_string()),
|
||||
_ => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidInput,
|
||||
"Invalid URL scheme",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn launch_firefox<C: CommandRunner>(
|
||||
url: String,
|
||||
private: bool,
|
||||
os: &str,
|
||||
) -> std::io::Result<String> {
|
||||
let validated_url: String = validate_url(url)?;
|
||||
let mut command = C::new();
|
||||
if os == "macos" {
|
||||
use mozbuild::config::MOZ_MACBUNDLE_ID;
|
||||
let mut args: [&str; 2] = ["--args", "-url"];
|
||||
if private {
|
||||
args[1] = "-private-window";
|
||||
}
|
||||
command
|
||||
.arg("-n")
|
||||
.arg("-b")
|
||||
.arg(MOZ_MACBUNDLE_ID)
|
||||
.args(&args)
|
||||
.arg(validated_url.as_str());
|
||||
} else if os == "windows" {
|
||||
let mut args: [&str; 2] = ["-osint", "-url"];
|
||||
if private {
|
||||
args[1] = "-private-window";
|
||||
}
|
||||
command.args(&args).arg(validated_url.as_str());
|
||||
}
|
||||
match command.spawn() {
|
||||
Ok(_) => generate_response(
|
||||
if private {
|
||||
"Successful private launch"
|
||||
} else {
|
||||
"Sucessful launch"
|
||||
},
|
||||
ResultCode::Success.into(),
|
||||
)?,
|
||||
Err(_) => generate_response(
|
||||
if private {
|
||||
"Failed private launch"
|
||||
} else {
|
||||
"Failed launch"
|
||||
},
|
||||
ResultCode::Error.into(),
|
||||
)?,
|
||||
};
|
||||
command.to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::io::Cursor;
|
||||
#[test]
|
||||
fn test_validate_url() {
|
||||
let valid_test_cases = vec![
|
||||
"https://example.com/".to_string(),
|
||||
"http://example.com/".to_string(),
|
||||
"file:///path/to/file".to_string(),
|
||||
"https://test.example.com/".to_string(),
|
||||
];
|
||||
|
||||
for input in valid_test_cases {
|
||||
let result = validate_url(input.clone());
|
||||
assert!(result.is_ok(), "Expected Ok, got Err");
|
||||
// Safe to unwrap because we know the result is Ok
|
||||
let ok_value = result.unwrap();
|
||||
assert_eq!(ok_value, input);
|
||||
}
|
||||
|
||||
assert!(matches!(
|
||||
validate_url("fakeprotocol://test.example.com/".to_string()).map_err(|e| e.kind()),
|
||||
Err(std::io::ErrorKind::InvalidInput)
|
||||
));
|
||||
|
||||
assert!(matches!(
|
||||
validate_url("invalidURL".to_string()).map_err(|e| e.kind()),
|
||||
Err(std::io::ErrorKind::InvalidData)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_message_length_valid() {
|
||||
let input: [u8; 4] = 256u32.to_ne_bytes();
|
||||
let mut cursor = Cursor::new(input);
|
||||
let length = read_message_length(&mut cursor);
|
||||
assert!(length.is_ok(), "Expected Ok, got Err");
|
||||
assert_eq!(length.unwrap(), 256);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_message_length_invalid_too_large() {
|
||||
let input: [u8; 4] = 1_000_000u32.to_ne_bytes();
|
||||
let mut cursor = Cursor::new(input);
|
||||
let result = read_message_length(&mut cursor);
|
||||
assert!(result.is_err());
|
||||
let error = result.err().unwrap();
|
||||
assert_eq!(error.kind(), io::ErrorKind::InvalidData);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_message_length_invalid_zero() {
|
||||
let input: [u8; 4] = 0u32.to_ne_bytes();
|
||||
let mut cursor = Cursor::new(input);
|
||||
let result = read_message_length(&mut cursor);
|
||||
assert!(result.is_err());
|
||||
let error = result.err().unwrap();
|
||||
assert_eq!(error.kind(), io::ErrorKind::InvalidData);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_message_string_valid() {
|
||||
let input_data = b"Valid UTF8 string!";
|
||||
let input_length = input_data.len() as u32;
|
||||
let message = read_message_string(&input_data[..], input_length);
|
||||
assert!(message.is_ok(), "Expected Ok, got Err");
|
||||
assert_eq!(message.unwrap(), "Valid UTF8 string!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_message_string_invalid() {
|
||||
let input_data: [u8; 3] = [0xff, 0xfe, 0xfd];
|
||||
let input_length = input_data.len() as u32;
|
||||
let result = read_message_string(&input_data[..], input_length);
|
||||
assert!(result.is_err());
|
||||
let error = result.err().unwrap();
|
||||
assert_eq!(error.kind(), io::ErrorKind::InvalidData);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_launch_regular_command_macos() {
|
||||
let url = "https://example.com";
|
||||
let result = launch_firefox::<MockCommand>(url.to_string(), false, "macos");
|
||||
assert!(result.is_ok());
|
||||
let command_line = result.unwrap();
|
||||
let correct_url_format = format!("-url {}", url);
|
||||
assert!(command_line.contains(correct_url_format.as_str()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_launch_regular_command_windows() {
|
||||
let url = "https://example.com";
|
||||
let result = launch_firefox::<MockCommand>(url.to_string(), false, "windows");
|
||||
assert!(result.is_ok());
|
||||
let command_line = result.unwrap();
|
||||
let correct_url_format = format!("-osint -url {}", url);
|
||||
assert!(command_line.contains(correct_url_format.as_str()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_launch_private_command_macos() {
|
||||
let url = "https://example.com";
|
||||
let result = launch_firefox::<MockCommand>(url.to_string(), true, "macos");
|
||||
assert!(result.is_ok());
|
||||
let command_line = result.unwrap();
|
||||
let correct_url_format = format!("-private-window {}", url);
|
||||
assert!(command_line.contains(correct_url_format.as_str()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_launch_private_command_windows() {
|
||||
let url = "https://example.com";
|
||||
let result = launch_firefox::<MockCommand>(url.to_string(), true, "windows");
|
||||
assert!(result.is_ok());
|
||||
let command_line = result.unwrap();
|
||||
let correct_url_format = format!("-osint -private-window {}", url);
|
||||
assert!(command_line.contains(correct_url_format.as_str()));
|
||||
}
|
||||
}
|
55
browser/app/nmhproxy/src/main.rs
Normal file
55
browser/app/nmhproxy/src/main.rs
Normal file
@ -0,0 +1,55 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
mod commands;
|
||||
use commands::ResultCode;
|
||||
use std::io::Error;
|
||||
use std::io::ErrorKind;
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
// The general structure of these functions is to print error cases to
|
||||
// stdout so that the extension can read them and then do error-handling
|
||||
// on that end.
|
||||
let message_length: u32 =
|
||||
commands::read_message_length(std::io::stdin()).or_else(|_| -> Result<u32, _> {
|
||||
commands::generate_response("Failed to read message length", ResultCode::Error.into())
|
||||
.expect("JSON error");
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Failed to read message length",
|
||||
));
|
||||
})?;
|
||||
let message: String = commands::read_message_string(std::io::stdin(), message_length).or_else(
|
||||
|_| -> Result<String, _> {
|
||||
commands::generate_response("Failed to read message", ResultCode::Error.into())
|
||||
.expect("JSON error");
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Failed to read message",
|
||||
));
|
||||
},
|
||||
)?;
|
||||
// Deserialize the message with the following expected format
|
||||
let native_messaging_json: commands::FirefoxCommand =
|
||||
serde_json::from_str(&message).or_else(|_| -> Result<commands::FirefoxCommand, _> {
|
||||
commands::generate_response(
|
||||
"Failed to deserialize message JSON",
|
||||
ResultCode::Error.into(),
|
||||
)
|
||||
.expect("JSON error");
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Failed to deserialize message JSON",
|
||||
));
|
||||
})?;
|
||||
commands::process_command(&native_messaging_json).or_else(|_| -> Result<bool, _> {
|
||||
commands::generate_response("Failed to process command", ResultCode::Error.into())
|
||||
.expect("JSON error");
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Failed to process command",
|
||||
));
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
@ -411,6 +411,12 @@ bin/libfreebl_64int_3.so
|
||||
;
|
||||
@BINPATH@/pingsender@BIN_SUFFIX@
|
||||
|
||||
; [ Native Messaging Host Proxy ]
|
||||
;
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
@BINPATH@/nmhproxy@BIN_SUFFIX@
|
||||
#endif
|
||||
|
||||
; [ Notification COM Server ]
|
||||
;
|
||||
#if defined(MOZ_NOTIFICATION_SERVER)
|
||||
|
@ -1577,6 +1577,7 @@ ${RemoveDefaultBrowserAgentShortcut}
|
||||
Push "crashreporter.exe"
|
||||
Push "default-browser-agent.exe"
|
||||
Push "minidump-analyzer.exe"
|
||||
Push "nmhproxy.exe"
|
||||
Push "pingsender.exe"
|
||||
Push "updater.exe"
|
||||
Push "mozwer.dll"
|
||||
|
@ -34,6 +34,14 @@ def escape_rust_string(value):
|
||||
return '"%s"' % result
|
||||
|
||||
|
||||
def generate_string(buildvar, output):
|
||||
buildconfig_var = buildconfig.substs.get(buildvar)
|
||||
if buildconfig_var is not None:
|
||||
output.write(
|
||||
f"pub const {buildvar}: &str = {escape_rust_string(buildconfig_var)};\n"
|
||||
)
|
||||
|
||||
|
||||
def generate(output):
|
||||
# Write out a macro which can be used within `include!`-like methods to
|
||||
# reference the topobjdir.
|
||||
@ -85,6 +93,10 @@ def generate(output):
|
||||
)
|
||||
)
|
||||
|
||||
# Write out some useful strings from the buildconfig.
|
||||
generate_string("MOZ_MACBUNDLE_ID", output)
|
||||
generate_string("MOZ_APP_NAME", output)
|
||||
|
||||
# Finally, write out some useful booleans from the buildconfig.
|
||||
output.write(generate_bool("MOZ_FOLD_LIBS"))
|
||||
output.write(generate_bool("NIGHTLY_BUILD"))
|
||||
|
@ -189,4 +189,5 @@ http3server = ["dep:arrayvec", "dep:bindgen", "dep:bitflags", "dep:bytes", "dep:
|
||||
ipcclientcerts-static = ["dep:bindgen", "dep:bitflags", "dep:memchr", "dep:nom", "dep:regex"]
|
||||
jsrust = ["dep:arrayvec", "dep:cc", "dep:env_logger", "dep:getrandom", "dep:hashbrown", "dep:indexmap", "dep:log", "dep:memchr", "dep:num-traits", "dep:once_cell", "dep:semver", "dep:smallvec", "dep:url"]
|
||||
mozwer_s = ["dep:getrandom", "dep:hashbrown", "dep:indexmap", "dep:once_cell", "dep:serde_json", "dep:uuid", "dep:windows-sys"]
|
||||
nmhproxy = ["dep:serde_json", "dep:url"]
|
||||
osclientcerts-static = ["dep:bindgen", "dep:bitflags", "dep:env_logger", "dep:log", "dep:memchr", "dep:nom", "dep:regex"]
|
||||
|
@ -654,6 +654,7 @@ class MacArtifactJob(ArtifactJob):
|
||||
"{product}-bin",
|
||||
"*.dylib",
|
||||
"minidump-analyzer",
|
||||
"nmhproxy",
|
||||
"pingsender",
|
||||
"plugin-container.app/Contents/MacOS/plugin-container",
|
||||
"updater.app/Contents/Frameworks/UpdateSettings.framework/UpdateSettings",
|
||||
|
@ -799,6 +799,7 @@ mac-signing:
|
||||
- "/Contents/MacOS/XUL"
|
||||
- "/Contents/MacOS/pingsender"
|
||||
- "/Contents/MacOS/minidump-analyzer"
|
||||
- "/Contents/MacOS/nmhproxy"
|
||||
- "/Contents/MacOS/*.dylib"
|
||||
- "/Contents/Resources/gmp-clearkey/*/*.dylib"
|
||||
- "/Contents/Frameworks/ChannelPrefs.framework"
|
||||
@ -842,6 +843,7 @@ mac-signing:
|
||||
- "/Contents/Library/LaunchServices/org.mozilla.updater"
|
||||
- "/Contents/MacOS/pingsender"
|
||||
- "/Contents/MacOS/minidump-analyzer"
|
||||
- "/Contents/MacOS/nmhproxy"
|
||||
- "/Contents/Frameworks/ChannelPrefs.framework"
|
||||
|
||||
- deep: false
|
||||
|
@ -31,6 +31,9 @@ RUST_TESTS = [
|
||||
"gkrust",
|
||||
]
|
||||
|
||||
if CONFIG["TARGET_OS"] in ("WINNT", "OSX"):
|
||||
RUST_TESTS += ["nmhproxy"]
|
||||
|
||||
# Code coverage builds link a bunch of Gecko bindings code from the style
|
||||
# crate, which is not used by our tests but would cause link errors.
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user