mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1836670 - Use NonNull in cssparser::CowRcStr. r=layout-reviewers,glandium,dlrobertson
This prevents the compiler from misoptimizing this code due to undefined behavior. Upstream PR: https://github.com/servo/rust-cssparser/pull/345 Differential Revision: https://phabricator.services.mozilla.com/D179921
This commit is contained in:
parent
b87b4a2527
commit
d4a4ca7c15
@ -332,7 +332,6 @@ run-if = !headless && (os == 'mac' || toolkit == 'android' || toolkit == 'gtk')
|
||||
[test_parse_rule.html]
|
||||
[test_parse_url.html]
|
||||
[test_parser_diagnostics_unprintables.html]
|
||||
skip-if = !debug # bug 1836670
|
||||
[test_pixel_lengths.html]
|
||||
[test_placeholder_restrictions.html]
|
||||
[test_pointer-events.html]
|
||||
|
47
third_party/rust/cssparser/src/cow_rc_str.rs
vendored
47
third_party/rust/cssparser/src/cow_rc_str.rs
vendored
@ -3,37 +3,24 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::borrow::{Borrow, Cow};
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::hash;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
use std::{cmp, fmt, hash, marker, mem, ops, slice, str, ptr};
|
||||
|
||||
/// A string that is either shared (heap-allocated and reference-counted) or borrowed.
|
||||
///
|
||||
/// Equivalent to `enum { Borrowed(&'a str), Shared(Rc<String>) }`, but stored more compactly.
|
||||
///
|
||||
/// FIXME(https://github.com/rust-lang/rfcs/issues/1230): use an actual enum if/when
|
||||
/// the compiler can do this layout optimization.
|
||||
/// * If `borrowed_len_or_max == usize::MAX`, then `ptr` represents `NonZero<*const String>`
|
||||
/// from `Rc::into_raw`.
|
||||
/// The lifetime parameter `'a` is irrelevant in this case.
|
||||
///
|
||||
/// * Otherwise, `ptr` represents the `NonZero<*const u8>` data component of `&'a str`,
|
||||
/// and `borrowed_len_or_max` its length.
|
||||
pub struct CowRcStr<'a> {
|
||||
/// FIXME: https://github.com/rust-lang/rust/issues/27730 use NonZero or Shared.
|
||||
/// In the meantime we abuse `&'static _` to get the effect of `NonZero<*const _>`.
|
||||
/// `ptr` doesn’t really have the 'static lifetime!
|
||||
ptr: &'static (),
|
||||
|
||||
/// * If `borrowed_len_or_max == usize::MAX`, then `ptr` represents `NonZero<*const String>`
|
||||
/// from `Rc::into_raw`.
|
||||
/// The lifetime parameter `'a` is irrelevant in this case.
|
||||
///
|
||||
/// * Otherwise, `ptr` represents the `NonZero<*const u8>` data component of `&'a str`,
|
||||
/// and `borrowed_len_or_max` its length.
|
||||
ptr: ptr::NonNull<()>,
|
||||
borrowed_len_or_max: usize,
|
||||
|
||||
phantom: PhantomData<Result<&'a str, Rc<String>>>,
|
||||
phantom: marker::PhantomData<Result<&'a str, Rc<String>>>,
|
||||
}
|
||||
|
||||
fn _static_assert_same_size<'a>() {
|
||||
@ -57,9 +44,9 @@ impl<'a> From<&'a str> for CowRcStr<'a> {
|
||||
let len = s.len();
|
||||
assert!(len < usize::MAX);
|
||||
CowRcStr {
|
||||
ptr: unsafe { &*(s.as_ptr() as *const ()) },
|
||||
ptr: unsafe { ptr::NonNull::new_unchecked(s.as_ptr() as *mut ()) },
|
||||
borrowed_len_or_max: len,
|
||||
phantom: PhantomData,
|
||||
phantom: marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,22 +61,22 @@ impl<'a> From<String> for CowRcStr<'a> {
|
||||
impl<'a> CowRcStr<'a> {
|
||||
#[inline]
|
||||
fn from_rc(s: Rc<String>) -> Self {
|
||||
let ptr = unsafe { &*(Rc::into_raw(s) as *const ()) };
|
||||
let ptr = unsafe { ptr::NonNull::new_unchecked(Rc::into_raw(s) as *mut ()) };
|
||||
CowRcStr {
|
||||
ptr: ptr,
|
||||
ptr,
|
||||
borrowed_len_or_max: usize::MAX,
|
||||
phantom: PhantomData,
|
||||
phantom: marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unpack(&self) -> Result<&'a str, *const String> {
|
||||
if self.borrowed_len_or_max == usize::MAX {
|
||||
Err(self.ptr as *const () as *const String)
|
||||
Err(self.ptr.as_ptr() as *const String)
|
||||
} else {
|
||||
unsafe {
|
||||
Ok(str::from_utf8_unchecked(slice::from_raw_parts(
|
||||
self.ptr as *const () as *const u8,
|
||||
self.ptr.as_ptr() as *const u8,
|
||||
self.borrowed_len_or_max,
|
||||
)))
|
||||
}
|
||||
@ -121,7 +108,7 @@ impl<'a> Drop for CowRcStr<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for CowRcStr<'a> {
|
||||
impl<'a> ops::Deref for CowRcStr<'a> {
|
||||
type Target = str;
|
||||
|
||||
#[inline]
|
||||
|
Loading…
Reference in New Issue
Block a user