From 5e43773158197be3bf0d9c7fe414280372c1673f Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 7 Feb 2018 00:01:53 +0100 Subject: [PATCH] Do not allow linking with entry itself Without this check, linking an entry with itself yields the following error: ERROR[ 1]: Entry is already borrowed: StoreId { base: Some("/home/m/.imag/store"), id: "notes/test" } ERROR[ 2]: Error when calling retrieve() -- caused: ERROR[ 3]: Error when calling get() Which is semantically correct, but the user may get confused by that. Instead, we print a nice error message that the entry cannot be linked to itself. This is not fixed in libimagentrylink itself, because libimagentrylink cannot be called for the same entry. If this would be possible, we would pass two `Entry` objects mutably to the link functionality routines. This is not possible with Rusts borrow semantics and therefor yields above error. We compare strings to check whether the user accidentially linked an entry with itself because we cannot get StoreIds from Entries because we cannot get the Entry two times from the store in the first place. So this is the best we have. --- bin/core/imag-link/src/main.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index fe2fc091..540e9393 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -61,6 +61,7 @@ use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagstore::error::StoreError; use libimagstore::store::FileLockEntry; +use libimagstore::storeid::StoreId; use libimagutil::warn_exit::warn_exit; use libimagutil::warn_result::*; @@ -134,7 +135,16 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I) .map_err_trace_exit_unwrap(1); } else { debug!("Linking internally: {:?} -> {:?}", from, entry); - let mut to_entry = match get_entry_by_name(rt, entry) { + + let from_id = StoreId::new_baseless(PathBuf::from(from)).map_err_trace_exit_unwrap(1); + let entr_id = StoreId::new_baseless(PathBuf::from(entry)).map_err_trace_exit_unwrap(1); + + if from_id == entr_id { + error!("Cannot link entry with itself. Exiting"); + ::std::process::exit(1) + } + + let mut to_entry = match rt.store().get(entr_id) { Ok(Some(e)) => e, Ok(None) => { warn!("No 'to' entry: {}", entry);