Thank you for your interest. I finally took some time tonight and added
a unit test for your exact problem. The problem duplicated itself
exactly. The @gref acts as a stack of ref pointers to the various
groups. When the level is less than the previously stored level we have
to unwind the stack. I'm not exactly sure what I was thinking with
that particular line. Here is the replacement line:
splice @gref, $level, @gref - $level, ();
We need to remove any levels above the level that we are moving back to
- the last code sort of did it in the wrong direction. This new chunk
lops off the branches correctly.
I've also added the following as part of the unit tests:
# test for correct stack unwinding during the parse_group phase
my $obj2 = File::KeePass->new;
my $G = $obj2->add_group({
title => 'hello',
});
$G = $obj2->add_group({
title => 'world',
group => $G,
});
$G = $obj2->add_group({
title => 'i am sam',
group => $G,
});
$G = $obj2->add_group({
title => 'goodbye',
});
$dump = eval { $obj2->dump_groups };
diag($dump);
my $ok = $obj2->parse_db($obj2->gen_db($pass), $pass);
my $dump2 = eval { $obj2->dump_groups };
#diag($dump);
is($dump, $dump2, "Dumps should match after gen_db->parse_db");
I got started on adding keepass2 files, I may try and get that done and
out to, but I'll get this patch out hopefully early next week. I'll
comment more on your other emails soon.
Thanks again.
Paul
On 11/29/2010 09:13 AM, Lester Hightower via RT wrote:
Show quoted text> Queue: File-KeePass
> Ticket<URL:
https://rt.cpan.org/Ticket/Display.html?id=63442>
>
> On Mon Nov 29 10:55:48 2010, lester.hightower@gmail.com wrote:
>> File::KeePass messes up the group hierarchy any time parse_groups()
>> encounters a structure where one moves more than one level "up" in a
>> tree. Here is an example:
>>
>> - hello
>> - world
>> - i am sam
>> - goodbye
>>
>> In this case, the group "goodbye" will mistakenly be placed inside of
>> the group "hello" instead of at the root level, and all later root
>> groups will be place an increasing level deeper. This problem only
>> seems to occur if the "move up" is greater than 1 level. I am pretty
>> sure there is a mistake inside the conditional "if ($previous_level>
>> $level)" in parse_groups() and I suspect that the issue is with the
>> splice() operation, but I am struggling to grok exactly what that code
>> is doing.
>>
>> It would be great if the original author could have a quick look at it
>> as he may see the problem straight away...
>>
>> Thanks.
>
> In follow up to this, I _think_ I figured this problem out but would
> sure like the original author to verify it.
>
> My tiny change in parse_groups():
>
> < splice @gref, $previous_level, $previous_level - $level, ();
>> splice @gref, -1*$previous_level, $previous_level - $level, ();
> which seems to fix the problem and is the desired behavior _if_ I am
> understanding the structure of @gref correctly.
>
> Sincerely,
> Lester Hightower
>