Skip to content

Commit

Permalink
Check raw entity IDs (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
Schottkyc137 committed May 11, 2024
1 parent 2a82770 commit e1741bd
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 3 deletions.
25 changes: 25 additions & 0 deletions vhdl_lang/src/analysis/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,17 @@ impl DesignRoot {
pub fn symbols(&self) -> &Symbols {
self.symbols.as_ref()
}

/// Gets an entity-ID from a raw `usize` value and checks that the entity ID is
/// valid, i.e., points to an existing [AnyEnt].
pub fn entity_id_from_raw(&self, raw: usize) -> Option<EntityId> {
let id = EntityId::from_raw(raw);
if self.arenas.is_valid_id(id) {
Some(id)
} else {
None
}
}
}

fn get_all_affected(
Expand Down Expand Up @@ -1285,6 +1296,7 @@ fn public_symbols<'a>(ent: EntRef<'a>) -> Box<dyn Iterator<Item = EntRef<'a>> +
#[cfg(test)]
mod tests {
use super::*;
use crate::analysis::tests::{check_no_diagnostics, LibraryBuilder};
use crate::syntax::test::{check_diagnostics, Code};

fn new_library_with_diagnostics(code: &Code, name: &str) -> (Library, Vec<Diagnostic>) {
Expand Down Expand Up @@ -1443,4 +1455,17 @@ end configuration;
assert_eq!(library.units.len(), 2);
assert_eq!(library.duplicates.len(), 1);
}

#[test]
pub fn rejects_illegal_raw_id() {
let mut builder = LibraryBuilder::new();
let code = builder.in_declarative_region("signal foo : natural;");
let (root, diagnostics) = builder.get_analyzed_root();
check_no_diagnostics(&diagnostics);
let (_, ent) = root
.item_at_cursor(code.source(), code.s1("foo").start())
.unwrap();
assert_eq!(root.entity_id_from_raw(ent.id.to_raw()), Some(ent.id));
assert_eq!(root.entity_id_from_raw(0xFFFF << 32), None);
}
}
12 changes: 11 additions & 1 deletion vhdl_lang/src/named_entity/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ impl LocalArena {
std::mem::transmute(std::pin::Pin::into_inner(item) as *mut AnyEnt)
}

pub fn contains(&self, id: LocalId) -> bool {
(id.0 as usize) < self.items.len()
}

fn panic_on_missing(&self, id: LocalId) {
if (id.0 as usize) < self.items.len() {
return;
Expand Down Expand Up @@ -115,6 +119,12 @@ impl<'a> FinalArena {
}
}

pub fn is_valid_id(&self, id: EntityId) -> bool {
self.refs
.get(&id.arena_id().0)
.is_some_and(|local_arena| local_arena.contains(id.local_id()))
}

pub fn link(&mut self, referenced: &FinalArena) {
for (id, arena) in referenced.refs.iter() {
self.refs.entry(*id).or_insert_with(|| arena.clone());
Expand Down Expand Up @@ -304,7 +314,7 @@ impl EntityId {

/// Returns an `EntityId` from a raw `usize` value
/// for deserialization purposes.
pub fn from_raw(id: usize) -> EntityId {
pub(crate) fn from_raw(id: usize) -> EntityId {
EntityId { id }
}

Expand Down
4 changes: 4 additions & 0 deletions vhdl_lang/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ impl Project {
) -> Vec<CompletionItem> {
list_completion_options(&self.root, source, cursor)
}

pub fn entity_id_from_raw(&self, raw: usize) -> Option<EntityId> {
self.root.entity_id_from_raw(raw)
}
}

/// Multiply cloneable value by cloning
Expand Down
4 changes: 2 additions & 2 deletions vhdl_ls/src/vhdl_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::io;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use vhdl_lang::{
kind_str, AnyEntKind, Concurrent, Config, Design, Diagnostic, EntHierarchy, EntRef, EntityId,
kind_str, AnyEntKind, Concurrent, Config, Design, Diagnostic, EntHierarchy, EntRef,
InterfaceEnt, Message, MessageHandler, Object, Overloaded, Project, Severity, SeverityMap,
Source, SrcPos, Token, Type, VHDLStandard,
};
Expand Down Expand Up @@ -466,7 +466,7 @@ impl VHDLServer {
.data
.clone()
.and_then(|val| serde_json::from_value::<usize>(val).ok())
.map(EntityId::from_raw);
.and_then(|raw| self.project.entity_id_from_raw(raw));
if let Some(id) = eid {
if let Some(text) = self.project.format_entity(id) {
params.documentation = Some(Documentation::MarkupContent(MarkupContent {
Expand Down

0 comments on commit e1741bd

Please sign in to comment.