Skip to content

Deleting a key while iterated upon will result in never-ending iterator #69

@vthib

Description

@vthib

See for example this reproducer:

#[test]
fn test_delete_key_while_iterating() {
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);

    // First, create the key we will iterate on
    let path = "Software\\WinRegRsTest\\DeleteKeyWhileIterating".to_owned();
    let (key, _disp) = hkcu.create_subkey(&path).unwrap();

    // Then, create two subkeys in it
    key.create_subkey("SubKey1").unwrap();
    key.create_subkey("SubKey2").unwrap();

    // Start iterating on the subkeys.
    let mut iter = key.enum_keys();
    let subkey = iter.next().unwrap();
    assert!(subkey.unwrap().starts_with("SubKey"));

    // Delete the key
    hkcu.delete_subkey_all(path).unwrap();

    // Use the iterator once again. It will never end and return
    // `Some(Err(ERROR_KEY_DELETED))` forever.
    let err = iter.next().unwrap().unwrap_err();
    assert_eq!(
        err.raw_os_error(),
        Some(Foundation::ERROR_KEY_DELETED as i32)
    );
    let err = iter.next().unwrap().unwrap_err();
    assert_eq!(
        err.raw_os_error(),
        Some(Foundation::ERROR_KEY_DELETED as i32)
    );
}

The issue is that the iterator never ends which can result in code hot-looping if they are not careful.

For example, this kind of code will never end:

let subkey_names = key.enum_keys().filter_map(|v| v.ok()).collect();

Of course, you could say that it is by design and the caller should handle errors
on his side to decide whether to stop the iteration or keep going. Hence my opening
of this issue to discuss it.

I have a PR ready to change the behavior so that on this particular error, the error is first returned, then the iterator returns None. Would it be ok for you?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions