Skip to content

Commit

Permalink
Add the Security framework
Browse files Browse the repository at this point in the history
Fixes #596.
  • Loading branch information
madsmtm committed Jan 12, 2025
1 parent 528b990 commit 161404a
Show file tree
Hide file tree
Showing 32 changed files with 848 additions and 121 deletions.
26 changes: 13 additions & 13 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions crates/header-translator/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,17 @@ impl Expr {
(TokenKind::Identifier, ident) => {
Token::Expr(if let Some(expr) = declaration_references.get(&ident) {
expr.clone()
} else {
let macro_invocation = context
.macro_invocations
.get(&MacroLocation::from_location(&token.get_location()))
.expect("expr macro invocation");
} else if let Some(macro_invocation) = context
.macro_invocations
.get(&MacroLocation::from_location(&token.get_location()))
{
Expr::MacroInvocation {
id: macro_invocation.id.clone(),
evaluated: None,
}
} else {
error!(?entity, ?token, "missing macro invocation in expr");
return Self::from_evaluated(entity);
})
}
(TokenKind::Literal, lit) => {
Expand Down
16 changes: 11 additions & 5 deletions crates/header-translator/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ impl Module {

for stmt in &module.stmts {
if let Some(item) = stmt.provided_item() {
let visibility = if item.name.starts_with("__") {
// Item name may conflict with module name, don't
// expose at all.
continue;
} else if item.name.starts_with('_') {
// Try to expose, but only to the rest of the crate.
"pub(crate)"
} else {
"pub"
};

item.location().assert_file(module_name);

let mut items = stmt.required_items();
Expand All @@ -156,11 +167,6 @@ impl Module {
cfg_gate_ln(items, &[] as &[Location], config, item.location())
)?;

let visibility = if item.name.starts_with('_') {
"pub(crate)"
} else {
"pub"
};
writeln!(
f,
"{visibility} use self::__{}::{};",
Expand Down
60 changes: 32 additions & 28 deletions crates/header-translator/src/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use proc_macro2::{TokenStream, TokenTree};
use crate::context::Context;
use crate::display_helper::FormatterFn;
use crate::id::ItemIdentifier;
use crate::stmt::is_bridged;
use crate::stmt::items_required_by_decl;
use crate::stmt::{anonymous_record_name, is_bridged};
use crate::thread_safety::ThreadSafety;
use crate::unexposed_attr::UnexposedAttr;

Expand Down Expand Up @@ -326,7 +326,7 @@ impl Primitive {
Some(match self {
Self::Char => return None, // Target-specific
Self::SChar | Self::Short | Self::Int | Self::Long | Self::LongLong => true,
Self::UChar | Self::UShort | Self::UInt | Self::ULong | Self::ULongLong => true,
Self::UChar | Self::UShort | Self::UInt | Self::ULong | Self::ULongLong => false,
Self::Float | Self::Double | Self::F32 | Self::F64 => true, // Unsure
Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::ISize => true,
Self::U8 | Self::U16 | Self::U32 | Self::U64 | Self::USize => false,
Expand Down Expand Up @@ -487,7 +487,7 @@ pub enum Ty {
is_bridged: bool,
},
Union {
id: ItemIdentifier<Option<String>>,
id: ItemIdentifier,
/// FIXME: This does not work for recursive structs.
fields: Vec<Ty>,
},
Expand Down Expand Up @@ -632,7 +632,10 @@ impl Ty {
let fields = if matches!(
id.name.as_deref(),
Some(
"MIDISysexSendRequest" | "MIDISysexSendRequestUMP" | "MIDIDriverInterface"
"MIDISysexSendRequest"
| "MIDISysexSendRequestUMP"
| "MIDIDriverInterface"
| "cssm_list_element"
)
) {
// Fake fields, we'll have to define it ourselves
Expand All @@ -653,11 +656,20 @@ impl Ty {

match declaration.get_kind() {
EntityKind::StructDecl => Self::Struct {
id: id.map_name(|name| name.unwrap_or_else(|| "UnknownStruct".into())),
id: id.map_name(|name| {
name.or_else(|| anonymous_record_name(&declaration, context))
.unwrap_or_else(|| "UnknownStruct".into())
}),
fields,
is_bridged: is_bridged(&declaration, context),
},
EntityKind::UnionDecl => Self::Union { id, fields },
EntityKind::UnionDecl => Self::Union {
id: id.map_name(|name| {
name.or_else(|| anonymous_record_name(&declaration, context))
.unwrap_or_else(|| "UnknownUnion".into())
}),
fields,
},
_ => {
error!(?declaration, "unknown record type decl");
Self::GenericParam {
Expand Down Expand Up @@ -1030,6 +1042,15 @@ impl Ty {
"intptr_t" => return Self::Primitive(Primitive::ISize),
"uintptr_t" => return Self::Primitive(Primitive::USize),

// include/sys/_types/_XXX.h
"u_char" => return Self::Primitive(Primitive::UChar),
"u_short" => return Self::Primitive(Primitive::UShort),
"u_int" => return Self::Primitive(Primitive::UInt),
"u_int8_t" => return Self::Primitive(Primitive::U8),
"u_int16_t" => return Self::Primitive(Primitive::U16),
"u_int32_t" => return Self::Primitive(Primitive::U32),
"u_int64_t" => return Self::Primitive(Primitive::U64),

// Varargs, still unsupported by Rust.
"__builtin_va_list" => return Self::Primitive(Primitive::VaList),

Expand Down Expand Up @@ -1246,24 +1267,14 @@ impl Ty {
items.push(id.clone());
items
}
Self::Struct { id, fields, .. } => {
Self::Struct { id, fields, .. } | Self::Union { id, fields, .. } => {
let mut items = Vec::new();
for field in fields {
items.extend(field.required_items());
}
items.push(id.clone());
items
}
Self::Union { id, fields, .. } => {
let mut items = Vec::new();
for field in fields {
items.extend(field.required_items());
}
if let Some(id) = id.clone().to_option() {
items.push(id);
}
items
}
Self::Fn {
is_variadic: _,
no_escape: _,
Expand Down Expand Up @@ -1604,12 +1615,7 @@ impl Ty {
write!(f, "{}", id.path())
}
Self::Union { id, .. } => {
if let Some(id) = id.clone().to_option() {
write!(f, "{}", id.path())
} else {
// TODO
write!(f, "UnknownUnion")
}
write!(f, "{}", id.path())
}
Self::Enum { id, .. } => {
write!(f, "{}", id.path())
Expand Down Expand Up @@ -2155,11 +2161,13 @@ impl Ty {
})
}

// FIXME: See https://github.com/rust-lang/rfcs/pull/3659
pub(crate) fn closed_enum_repr(&self) -> impl fmt::Display + '_ {
FormatterFn(move |f| match self {
Self::Primitive(Primitive::NSInteger) => write!(f, "#[repr(isize)] // NSInteger"),
Self::Primitive(Primitive::NSUInteger) => write!(f, "#[repr(usize)] // NSUInteger"),
Self::Primitive(Primitive::U32) => write!(f, "#[repr(u32)]"),
Self::Primitive(Primitive::Int) => write!(f, "#[repr(i32)] // c_int"),
_ => panic!("invalid closed enum repr: {self:?}"),
})
}
Expand Down Expand Up @@ -2436,11 +2444,7 @@ impl Ty {
}

pub(crate) fn is_record(&self, s: &str) -> bool {
match self {
Self::Struct { id, .. } if id.name == s => true,
Self::Union { id, .. } if id.name.as_deref() == Some(s) => true,
_ => false,
}
matches!(self, Self::Struct { id, .. } | Self::Union { id, .. } if id.name == s)
}

pub(crate) fn is_enum_through_typedef(&self) -> bool {
Expand Down
53 changes: 48 additions & 5 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,45 @@ pub(crate) fn is_bridged(entity: &Entity<'_>, context: &Context<'_>) -> bool {
is_bridged
}

pub(crate) fn anonymous_record_name(entity: &Entity<'_>, context: &Context<'_>) -> Option<String> {
let parent = entity.get_semantic_parent()?;

if !matches!(
parent.get_kind(),
EntityKind::StructDecl | EntityKind::UnionDecl
) {
return None;
}

let parent_id = ItemIdentifier::new_optional(&parent, context)
.map_name(|name| name.or_else(|| anonymous_record_name(&parent, context)))
.to_option()?;

// Find the field name for this.
//
// UnionDecl/StructDecl comes first, then the matching FieldDecl.
let mut just_found_record = false;
let mut field_name = None;
immediate_children(&parent, |searched, _span| match searched.get_kind() {
EntityKind::FieldDecl => {
if just_found_record {
field_name = Some(searched.get_name().expect("field name"));
just_found_record = false;
}
}
EntityKind::UnionDecl | EntityKind::StructDecl => {
if searched == *entity {
just_found_record = true;
}
}
_ => {}
});

let field_name = field_name?;

Some(format!("{}_{}", parent_id.name, field_name))
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub enum Counterpart {
#[default]
Expand Down Expand Up @@ -1105,7 +1144,8 @@ impl Stmt {
| EntityKind::ObjCProtocolRef
| EntityKind::ParmDecl
| EntityKind::EnumDecl
| EntityKind::IntegerLiteral => {}
| EntityKind::IntegerLiteral
| EntityKind::BinaryOperator => {}
EntityKind::ObjCIndependentClass => {
// TODO: Might be interesting?
}
Expand Down Expand Up @@ -1197,7 +1237,10 @@ impl Stmt {
}
EntityKind::StructDecl | EntityKind::UnionDecl => {
let is_union = entity.get_kind() == EntityKind::UnionDecl;
let Some(id) = ItemIdentifier::new_optional(entity, context).to_option() else {
let id = ItemIdentifier::new_optional(entity, context)
.map_name(|name| name.or_else(|| anonymous_record_name(entity, context)))
.to_option();
let Some(id) = id else {
warn!(?entity, "skipped anonymous union/struct");
return vec![];
};
Expand Down Expand Up @@ -2421,11 +2464,11 @@ impl Stmt {
} else {
write!(f, "Encoding::Struct")?;
}
write!(f, "({:?}, &[", encoding_name.as_deref().unwrap_or(&id.name),)?;
writeln!(f, "({:?}, &[", encoding_name.as_deref().unwrap_or(&id.name),)?;
for (_, _, ty) in fields {
write!(f, "{},", ty.record_encoding())?;
writeln!(f, " {},", ty.record_encoding())?;
}
write!(f, "])")?;
write!(f, " ])")?;
Ok(())
});

Expand Down
7 changes: 6 additions & 1 deletion crates/header-translator/src/unexposed_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl UnexposedAttr {
| "CF_AVAILABLE_MAC"
| "CF_DEPRECATED"
| "CF_ENUM_AVAILABLE"
| "CF_ENUM_DEPRECATED"
| "CF_SWIFT_UNAVAILABLE"
| "CG_AVAILABLE_BUT_DEPRECATED"
| "CG_AVAILABLE_STARTING"
Expand Down Expand Up @@ -242,6 +243,7 @@ impl UnexposedAttr {
| "__IOS_PROHIBITED"
| "__IOS_UNAVAILABLE"
| "__OSX_UNAVAILABLE"
| "__SECURETRANSPORT_API_DEPRECATED"
| "__SWIFT_UNAVAILABLE"
| "__TVOS_PROHIBITED"
| "__TVOS_UNAVAILABLE"
Expand All @@ -254,6 +256,7 @@ impl UnexposedAttr {
| "CF_AUTOMATED_REFCOUNT_UNAVAILABLE"
| "CG_OBSOLETE"
| "CS_UNAVAILABLE_EMBEDDED"
| "CSSM_DEPRECATED"
| "deprecated"
| "DEPRECATED_ATTRIBUTE"
| "DISPATCH_UNAVAILABLE"
Expand All @@ -274,7 +277,9 @@ impl UnexposedAttr {
| "NS_UNAVAILABLE"
| "UNAVAILABLE_ATTRIBUTE"
| "UT_AVAILABLE_BEGIN"
| "MP_DEPRECATED_BEGIN" => None,
| "MP_DEPRECATED_BEGIN"
| "SEC_ASN1_API_DEPRECATED"
| "SECUREDOWNLOAD_API_DEPRECATED" => None,
s if s.starts_with("AVAILABLE_MAC_OS_X_VERSION_") => None,
s if s.starts_with("DEPRECATED_IN_MAC_OS_X_VERSION_") => None,
s if s.starts_with("FILEPROVIDER_API_AVAILABILITY_") => None,
Expand Down
Loading

0 comments on commit 161404a

Please sign in to comment.