Skip to content

Commit

Permalink
Fix the bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
dburgener committed Sep 26, 2023
1 parent 21639fd commit 7957c74
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 11 deletions.
21 changes: 21 additions & 0 deletions data/expected_cil/associate.cil
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,20 @@
(typeattribute resource)
(typeattribute bin)
(typeattributeset resource (bin))
(typeattribute dom_with_mix)
(typeattributeset domain (dom_with_mix))
(type dom_with_mix-mix)
(roletype object_r dom_with_mix-mix)
(typeattributeset resource (dom_with_mix-mix))
(typeattribute dom_with_mix_2)
(typeattributeset domain (dom_with_mix_2))
(typeattribute foo)
(typeattributeset domain (foo))
(type kernel_sid)
(roletype system_r kernel_sid)
(typeattributeset domain (kernel_sid))
(typeattribute mix)
(typeattributeset resource (mix))
(typeattribute nest_parent)
(typeattributeset domain (nest_parent))
(typeattribute nest_parent-nest_resource)
Expand Down Expand Up @@ -170,6 +179,14 @@
(typeattribute diamond2)
(typeattributeset foo (diamond2))
(typeattributeset domain (diamond2))
(typeattribute dom_with_mix_2-mix)
(typeattributeset mix (dom_with_mix_2-mix))
(typeattributeset resource (dom_with_mix_2-mix))
(type dom_with_mix_3)
(roletype system_r dom_with_mix_3)
(typeattributeset dom_with_mix (dom_with_mix_3))
(typeattributeset dom_with_mix_2 (dom_with_mix_3))
(typeattributeset domain (dom_with_mix_3))
(typeattribute foo-tmp)
(typeattributeset tmp (foo-tmp))
(typeattributeset resource (foo-tmp))
Expand Down Expand Up @@ -223,6 +240,10 @@
(typeattributeset diamond1 (diamond3))
(typeattributeset diamond2 (diamond3))
(typeattributeset domain (diamond3))
(type dom_with_mix_3-mix)
(roletype object_r dom_with_mix_3-mix)
(typeattributeset dom_with_mix_2-mix (dom_with_mix_3-mix))
(typeattributeset resource (dom_with_mix_3-mix))
(type baz-tmp)
(roletype object_r baz-tmp)
(typeattributeset bar-tmp (baz-tmp))
Expand Down
12 changes: 12 additions & 0 deletions data/policies/associate.cas
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,15 @@ virtual domain diamond2 inherits foo {}

// Gets two copies of associated resources via multiple inheritance, but they should collapse to one
domain diamond3 inherits diamond1, diamond2 {}


virtual resource mix {}

virtual domain dom_with_mix {
resource mix {}
}

@associate([mix])
virtual domain dom_with_mix_2 {}

domain dom_with_mix_3 inherits dom_with_mix, dom_with_mix_2 {}
16 changes: 10 additions & 6 deletions src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1528,11 +1528,17 @@ fn generate_type_no_parent_errors(missed_types: Vec<&TypeInfo>, types: &TypeMap)
ret
}

fn get_synthetic_resource_name(
pub fn get_synthetic_resource_name(
dom_name: &CascadeString,
associated_resource: &CascadeString,
) -> CascadeString {
format!("{}.{}", dom_name, associated_resource).into()
let cs_name = format!("{}.{}", dom_name, associated_resource);
// We keep the range of the *resource* part specifically, which should always be where this
// resource was defined
match associated_resource.get_range() {
Some(range) => CascadeString::new(cs_name, range),
None => CascadeString::from(cs_name)
}
}

fn create_synthetic_resource(
Expand Down Expand Up @@ -1562,10 +1568,8 @@ fn create_synthetic_resource(
let res_name = get_synthetic_resource_name(&dom_info.name, class_string);
if types.get(res_name.as_ref()).is_some() {
// A synthetic type with this name already exists, due to a nested association
// TODO: I don't think it's an accurate assumption that dom_info is definitely the child in
// this case. It's just whichever one happens to be done via annotation
return Err(
match make_duplicate_associate_error(types, dom_info, &res_name) {
match make_duplicate_associate_error(types, dom_info, &class_string) {
Some(e) => e.into(),
None => ErrorItem::Internal(InternalError::new()),
},
Expand Down Expand Up @@ -1684,7 +1688,7 @@ fn interpret_associate(
let potential_resources: BTreeMap<_, _> = associate
.resources
.iter()
.map(|r| (r.name.as_ref(), (r, false)))
.map(|r| (r.name().as_ref(), (r, false)))
.collect();

for (_, (res, _)) in potential_resources.iter().filter(|(_, (_, seen))| !seen) {
Expand Down
50 changes: 45 additions & 5 deletions src/internal_rep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ pub type TypeMap = AliasMap<TypeInfo>;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AssociatedResource {
pub name: CascadeString,
pub doms: BTreeSet<Option<CascadeString>>,
pub ranges: BTreeMap<String, Range<usize>>,
name: CascadeString,
doms: BTreeSet<Option<CascadeString>>,
ranges: BTreeMap<String, Range<usize>>,
}

impl AssociatedResource {
Expand All @@ -46,6 +46,10 @@ impl AssociatedResource {
self.ranges.get(resource_name).cloned()
}

pub fn name(&self) -> &CascadeString {
&self.name
}

pub fn get_class_names(&self) -> Vec<String> {
self.doms
.iter()
Expand Down Expand Up @@ -564,6 +568,10 @@ impl TypeInfo {
self.is_resource(types) && self.name.as_ref().contains('.')
}

pub fn get_associated_dom_name(&self) -> Option<&str> {
self.name.as_ref().split_once('.').map(|split| split.0)
}

// Returns false if this type is explicitly declared in source code, and true otherwise
pub fn is_synthetic(&self) -> bool {
self.name.get_range().is_none()
Expand Down Expand Up @@ -610,18 +618,50 @@ impl TypeInfo {
// specifically associations specifically in source, rather than somehow derived by the
// compiler
pub fn explicitly_associates(&self, associate_name: &str) -> Option<Range<usize>> {
use crate::compile::get_synthetic_resource_name;

for ann in &self.annotations {
if let AnnotationInfo::Associate(associations) = ann {
if let AnnotationInfo::Associate(associations) | AnnotationInfo::NestAssociate(associations) = ann {
for res in &associations.resources {
if res.string_is_instance(&CascadeString::from(associate_name))
&& res.get_range(associate_name).is_some()
{
// I think the issue is that this get_range() is returning None
// In other news, I'm an idiot. We are in a block for an if .is_some() on
// the exact same thing
return res.get_range(associate_name);
}
}
}
}
None
let ar_range = self.associated_resources
.iter()
.find(|a| a.string_is_instance(&associate_name.into()))
.and_then(|ar| {
ar.get_range(
get_synthetic_resource_name(&self.name, &associate_name.into())
.as_ref(),
)
});

if ar_range.is_some() {
return ar_range;
}

// If the resource is foo.bar, and we are foo, we need to check bar as well. If the reason
// is bar and we are foo, we need to check foo.bar as well
match associate_name.split_once('.') {
Some((dom_name, res_name)) => {
if dom_name == self.name {
self.explicitly_associates(res_name)
} else {
None
}
}
None => {
self.explicitly_associates(get_synthetic_resource_name(&self.name, &associate_name.into()).as_ref())
}
}
}

pub fn get_aliases(&self) -> BTreeSet<&CascadeString> {
Expand Down

0 comments on commit 7957c74

Please sign in to comment.