Merge pull request #184 from matthiasbeyer/libimagstore/fix-179
Check whether the StoreId is inside the store
This commit is contained in:
commit
ebb076c9fd
2 changed files with 23 additions and 0 deletions
|
@ -19,6 +19,7 @@ pub enum StoreErrorKind {
|
|||
IoError,
|
||||
StorePathExists,
|
||||
StorePathCreate,
|
||||
StorePathOutsideStore,
|
||||
LockPoisoned,
|
||||
EntryAlreadyBorrowed,
|
||||
EntryAlreadyExists,
|
||||
|
@ -37,6 +38,7 @@ fn store_error_type_as_str(e: &StoreErrorKind) -> &'static str {
|
|||
&StoreErrorKind::IoError => "File Error",
|
||||
&StoreErrorKind::StorePathExists => "Store path exists",
|
||||
&StoreErrorKind::StorePathCreate => "Store path create",
|
||||
&StoreErrorKind::StorePathOutsideStore => "Store path would be outside of store",
|
||||
&StoreErrorKind::LockPoisoned
|
||||
=> "The internal Store Lock has been poisoned",
|
||||
&StoreErrorKind::EntryAlreadyBorrowed => "Entry is already borrowed",
|
||||
|
|
|
@ -129,6 +129,10 @@ impl Store {
|
|||
|
||||
/// Creates the Entry at the given location (inside the entry)
|
||||
pub fn create<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
|
||||
if !self.id_in_store(&id) {
|
||||
return Err(StoreError::new(StoreErrorKind::StorePathOutsideStore, None));
|
||||
}
|
||||
|
||||
let hsmap = self.entries.write();
|
||||
if hsmap.is_err() {
|
||||
return Err(StoreError::new(StoreErrorKind::LockPoisoned, None))
|
||||
|
@ -148,6 +152,10 @@ impl Store {
|
|||
/// Borrow a given Entry. When the `FileLockEntry` is either `update`d or
|
||||
/// dropped, the new Entry is written to disk
|
||||
pub fn retrieve<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
|
||||
if !self.id_in_store(&id) {
|
||||
return Err(StoreError::new(StoreErrorKind::StorePathOutsideStore, None));
|
||||
}
|
||||
|
||||
self.entries
|
||||
.write()
|
||||
.map_err(|_| StoreError::new(StoreErrorKind::LockPoisoned, None))
|
||||
|
@ -202,6 +210,10 @@ impl Store {
|
|||
|
||||
/// Delete an entry
|
||||
pub fn delete(&self, id: StoreId) -> Result<()> {
|
||||
if !self.id_in_store(&id) {
|
||||
return Err(StoreError::new(StoreErrorKind::StorePathOutsideStore, None));
|
||||
}
|
||||
|
||||
let mut entries_lock = self.entries.write();
|
||||
if entries_lock.is_err() {
|
||||
return Err(StoreError::new(StoreErrorKind::LockPoisoned, None))
|
||||
|
@ -218,6 +230,15 @@ impl Store {
|
|||
entries.remove(&id);
|
||||
remove_file(&id).map_err(|e| StoreError::new(StoreErrorKind::FileError, Some(Box::new(e))))
|
||||
}
|
||||
|
||||
fn id_in_store(&self, path: &StoreId) -> bool {
|
||||
path.canonicalize()
|
||||
.map(|can| {
|
||||
can.starts_with(&self.location)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
// we return false, as fs::canonicalize() returns an Err(..) on filesystem errors
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Store {
|
||||
|
|
Loading…
Reference in a new issue