intermittent "index out of range" on preview
AGBrown opened this issue · comments
(keepass v2.45, this plugin v1.2.0)
I see the following error in the preview window, but only intermittently - I either see a list of passwords or this error.
Failed to generate a password.
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
If I use the plugin as the default password generator, this just results in intermittently not getting a password at all in the password field.
The previous version I used (I think it was 1.1.2 but I'm not certain) would, with some more restrictive settings, give a list with some entries and others with just an error text along the lines of "could not generate" (sorry again, I don't remember the exact text). With this version it's more all or nothing.
If the new approach is by design, I think the previous approach was preferable.
I think you have a minor bug in the logic in ConstantMutator
that causes an ArgumentOutOfRangeException
. That seems to be where I get an exception thrown when I debug the plugin, at least.
I've created a PR and submitted it for you, and linked to this issue. Even if you want to reject the PR and fix yourself (which wouldn't bother me) then at least it shows where the bug is and gives you a unit test to play with. That last bit is important as I've had to make an assumption about how you want it to behave, which I'm not sure is correct. If it's wrong then it's easy enough for either one of us to correct the assumption, the test and the code.
Thanks for the pull request. I've not merged it, but have created a branch that I believe fixes your specific issue. Looks like no trailing whitespace is the cause. I wouldn't have found it without your unit tests though, so a big thank you for the effort you've put in :-)
I'm puzzled how you end up with a passphrase without trailing whitespace in KeePass, as the code path that uses mutators forces U+0020
as the word delimiter (and then fixes it up afterwards). Are you able to post or PM your KeePass configuration (either screenshot or XML)? I'm concerned there's a deeper issue we've both missed.
I'm concerned there's a deeper issue we've both missed.
Agreed. This could well be a case of fixing the symptom rather than the cause - I didn't fully characterise the input parameter space and see which combinations threw exceptions through the whole code path.
All I did was attach the debugger and catch two or three which all threw at the insert line in the ConstantMutator
. These all looked like it was where: the ConstantMutator
chose the end of the phrase; and the StringBuilder
looked something like "foo bar fizz buzz 6"
when it was passed in to Mutate
. I made a guess it was related to the NumericMutator
also having chosen the end position as a result. I may therefore have completely missed the underlying issue - particularly as I don't know the actual/intended design at all, sorry!
Attached is the KeePass.config.xml
Which is from this config:
bugfix/i3-constantmutator
on my fork has a better test which combines the three mutators in use in that config above in the same order as your plugin does (MultipleMutatorIntegrationFixture
) and tests across the input parameter space. Strangely, test failures before your fix is applied (AGBrown/readablepassphrasegenerator@74e445a) are not consistent, but they do happen every other test run or so (I would have expected them to always happen for EndOfPhrase on both numeric and constant mutations?). Once your fix is applied I don't see any test failures on several minutes of runs (but didn't run it for hours).
Feel free to grab the test code I've put together if it helps. I'm sure I'll get round to deleting my fork at some point in the future, but will certainly leave it up there for the moment for you.
Example failure inputs before your fix is applied (these don't fail every time though):
CombineMutators(Never,1,Anywhere,1,EndOfPhrase
CombineMutators(Anywhere,2,Anywhere,2,EndOfPhrase
CombineMutators(Anywhere,3,Anywhere,2,EndOfPhrase
CombineMutators(Never,1,Anywhere,2,Anywhere)
CombineMutators(StartOfWord,2,Anywhere,2,EndOfPhrase)
I think I know what's happening (although I can't reproduce it on my computer for some reason). The NumericMutator
adds a number at the end of the passphrase and does not leave any trailing whitespace. So it's a combination of mutators, as your test has found.
Thanks again for your help with this one!
Thanks again for your help with this one!
No problem
Intermittent test failures are mildly concerning though - the tests should be completely deterministic and repeatable for EndOfPhrase
in all positions, for instance. So it's either a problem with the word phrases being generated for the test input, a problem inside the mutators, or some randomness that is used inside the first two mutators (I haven't looked at the code so I'm not sure if there is any). It wouldn't be hard to rule out the first of those just by using a fixed input phrase of "foo bar fizz buzz"
and see if the test failures are consistent, even if that goes against Constrained Non-Determinism.
I won't spend more time on this though if you aren't going to adopt the unit test project. I'll look out for a release at some point that fixes the original issue reported. Thank you for responding to this so quickly!
Just an FYI, I'm swamped at work at the moment, so might be a week or so before I have enough time to fix this and do an update.
Fixed in Version 1.2.1
Thanks again for your help, @AGBrown