/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/// A slice into the backing string. /// /// This type is only valid as long as the [`MozURL`] which it was pulled from is /// valid. In C++, this type implicitly converts to a `nsDependentCString`, and is /// an implementation detail. /// /// This type exists because, unlike `&str`, this type is safe to return over FFI. #[repr(C)] pubstruct SpecSlice<'a> {
data: *const u8,
len: u32,
_marker: PhantomData<&'a [u8]>,
}
impl<'a> From<&'a str> for SpecSlice<'a> { fn from(s: &'a str) -> Self {
SpecSlice {
data: s.as_ptr(),
len: u32::try_from(s.len()).expect("string length not representable in u32"),
_marker: PhantomData,
}
}
}
/// The [`MozURL`] reference-counted threadsafe URL type. This type intentionally /// implements no XPCOM interfaces, and all method calls are non-virtual. #[repr(C)] pubstruct MozURL { pub url: Url,
refcnt: AtomicRefcnt,
}
impl MozURL { #[must_use] pubfn from_url(url: Url) -> RefPtr<Self> { // Actually allocate the URL on the heap. This is the only place we actually // create a [`MozURL`], other than in `clone()`. unsafe {
RefPtr::from_raw(Box::into_raw(Box::new(Self {
url,
refcnt: AtomicRefcnt::new(),
})))
.expect("MozURL created OK")
}
}
}
#[no_mangle] pubunsafeextern"C"fn mozurl_release(url: &MozURL) { let rc = url.refcnt.dec(); if rc == 0 {
drop(Box::from_raw(ptr::from_ref::<MozURL>(url).cast_mut()));
}
}
// xpcom::RefPtr support unsafeimpl RefCounted for MozURL { unsafefn addref(&self) {
mozurl_addref(self);
} unsafefn release(&self) {
mozurl_release(self);
}
}
// Allocate a new MozURL object with a RefCnt of 1, and store a pointer to it // into url. #[no_mangle] pubextern"C"fn mozurl_new(
result: &mut *const MozURL,
spec: &nsACString,
base: Option<&MozURL>,
) -> nsresult {
*result = ptr::null_mut();
let spec = try_or_malformed!(str::from_utf8(spec)); let url = iflet Some(base) = base {
try_or_malformed!(base.url.join(spec))
} else {
try_or_malformed!(parser().parse(spec))
};
MozURL::from_url(url).forget(result);
NS_OK
}
/// Allocate a new [`MozURL`] object which is a clone of the original, and store a /// pointer to it into newurl. #[no_mangle] pubextern"C"fn mozurl_clone(url: &MozURL, newurl: &mut *const MozURL) {
MozURL::from_url(url.url.clone()).forget(newurl);
}
#[no_mangle] pubextern"C"fn mozurl_origin(url: &MozURL, origin: &mut nsACString) { let origin_str = if url.as_ref().starts_with("about:blank") {
None
} else {
get_origin(url)
};
let origin_str = origin_str.unwrap_or_else(|| { // nsIPrincipal stores the uuid, so the same uuid is returned everytime. // We can't do that for MozURL because it can be used across threads. // Storing uuid would mutate the object which would cause races between // threads.
format!("moz-nullprincipal:{{{}}}", Uuid::new_v4())
});
// NOTE: Try to re-use the allocation we got from rust-url, and transfer // ownership of the buffer to C++. letmut o = nsCString::from(origin_str);
origin.take_from(&mut o);
}
// Helper macro for debug asserting that we're the only reference to MozURL.
macro_rules! debug_assert_mut {
($e:expr) => {
debug_assert_eq!($e.refcnt.get(), 1, "Cannot mutate an aliased MozURL!");
};
}
if new_port > i32::from(u16::MAX) { return NS_ERROR_UNEXPECTED;
}
if url.cannot_be_a_base() { return NS_ERROR_MALFORMED_URI;
}
#[expect(clippy::cast_sign_loss, reason = "not possible due to first match arm")] let port = match new_port {
new if new < 0 || i32::from(u16::MAX) <= new => None,
new if Some(new as u16) == default_port(url.scheme()) => None,
new => Some(new as u16),
};
try_or_malformed!(url.set_port(port));
NS_OK
}
match (url1.path_segments(), url2.path_segments()) {
(Some(mut path1), Some(mut path2)) => { // Exhaust the part of the iterators that match whilelet (Some(p1), Some(p2)) = (&path1.next(), &path2.next()) { if p1 != p2 { break;
}
}
result.truncate(); for _ in path1 {
result.append("../");
} for p2 in path2 {
result.append(p2);
result.append("/");
}
}
_ => {
result.assign(url2.as_ref());
}
}
NS_OK
}
/// This type is used by nsStandardURL #[no_mangle] pubextern"C"fn rusturl_parse_ipv6addr(input: &nsACString, addr: &mut nsACString) -> nsresult { let ip6 = try_or_malformed!(str::from_utf8(input)); let host = try_or_malformed!(url::Host::parse(ip6));
_ = write!(addr, "{host}");
NS_OK
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.