Skip to content

Rust allows unsafe stack references to be pushed into HashMap under some circumstances #10078

Closed
@pythonesque

Description

@pythonesque

Not sure of the precise underlying bug, but a testcase is this:

use std::hashmap::{HashMap};

enum Entry<'self,T> {
    Ref(&'self Entry<'self,T>),
    Val(T)
}

pub struct Table<'self> {
    priv inner: HashMap<&'self str, &'self Entry<'self, int>>
}

pub trait ReferenceMap<K,V> {
    fn add<'a>(&mut self, K, V) -> bool;
}
impl<'self, K, V, T : MutableMap<K,&'self Entry<'self,V>>> ReferenceMap<K,V> for T {
    fn add<'a>(&mut self, key : K, value : V) -> bool {
        // the use of &Val(value) *should* be disallowed.
        !self.contains_key(&key) && self.insert(key, &Val(value)) // ****
    }
}

impl<'self> Table<'self> {
    pub fn new() -> Table<'self> {
        Table { inner: HashMap::new() }
    }
}

impl<'self> Table<'self> {
    pub fn add<'a>(&mut self, key : &'self str, value : int) -> bool {
        self.inner.add(key, value)
    }

    pub fn lookup(&'self self, key : &'self str) -> Option<&'self int> {
        match self.deref(key) {
            Some(&Val(ref val)) => Some(val),
            _ => None
        }
    }
    fn deref(&'self self, key : &'self str) -> Option<&'self Entry<'self, int>> {
        match self.inner.find(&key) {
            Some(entry) => {
                let mut ptr = *entry;

                loop {
                    match *ptr {
                        Ref(next) => ptr = next,
                        _ => return Some(ptr),
                    }
                }
            },
            None => None
        }
    }
}


fn main() {
    let mut t = Table::new();

    t.add("foo", 2);

    // *incorrectly* prints None
    println!("{:?}", t.lookup("foo"));

    // crashes with 'enum value matched no variant'
    // println!("{:?}", t);
}

Specifically, the line marked **** is where we see the problem manifest itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions