Issue 8557 - mdb_put may cause a cursor malfunction
Summary: mdb_put may cause a cursor malfunction
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-01-03 21:04 UTC by lazarev.michael@gmail.com
Modified: 2018-02-09 18:59 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description lazarev.michael@gmail.com 2017-01-03 21:04:58 UTC
Full_Name: Michael Lazarev
Version: 
OS: Linux, FreeBSD
URL: ftp://ftp.openldap.org/incoming/mdb_put_test.c
Submission from: (NULL) (128.70.151.136)


After a number of mdb_put calls, mdb_cursor_get with MDB_LAST operation
positions the cursor incorrectly. Test code is submitted here:
ftp://ftp.openldap.org/incoming/mdb_put_test.c
Comment 1 Hallvard Furuseth 2017-01-05 08:47:31 UTC
On 03/01/17 22:04, lazarev.michael@gmail.com wrote:
> After a number of mdb_put calls, mdb_cursor_get with MDB_LAST operation
> positions the cursor incorrectly. Test code is submitted here:
> ftp://ftp.openldap.org/incoming/mdb_put_test.c

The C_EOF flag is doubly broken here, and maybe ill-defined:

Previous mdb_cursor_last() set C_EOF as a "cursor is on the last page"
hint, cursor_put() did not clear it in this cursor when putting
through another cursor, and then next cursor_last() uses the hint in
"if (!(mc->mc_flags & C_EOF))" when the cursor is no longer at the end.

However, elsewhere the flag is seen as "cursor is beyond last item":
mdb_cursor_next(), MDB_GET_MULTIPLE, mdb_cursor_count().  It is set
that way after mdb_cursor_sibling(<right>) fails.  But it's not used
consistently that way either: At least MDB_GET_CURRENT, MDB_PREV,
put(MDB_CURRENT) succeed with C_EOF set.  (And they don't move
the cursor to the last item first.)

As for the "cursor is on last page" hint, page_search() & co could at
least avoid some page_get()s without using C_EOF: If C_INITIALIZED is
set, then while mc_pg[] and mc_ki[] are correct it can just walk
down the cursor without doing page_get().  If a _pg or _ki needs to
change, it can switch to the regular page_seaarch() code.  Helps
write-txns and MDB_VL32, but not read-only txns.



Comment 2 Howard Chu 2017-01-11 11:34:52 UTC
lazarev.michael@gmail.com wrote:
> Full_Name: Michael Lazarev
> Version:
> OS: Linux, FreeBSD
> URL: ftp://ftp.openldap.org/incoming/mdb_put_test.c
> Submission from: (NULL) (128.70.151.136)
>
>
> After a number of mdb_put calls, mdb_cursor_get with MDB_LAST operation
> positions the cursor incorrectly. Test code is submitted here:
> ftp://ftp.openldap.org/incoming/mdb_put_test.c
>
>
Thanks for the report. Fixed now in git.

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 3 Howard Chu 2017-01-11 13:33:40 UTC
changed notes
changed state Open to Test
moved from Incoming to Software Bugs
Comment 4 OpenLDAP project 2018-02-09 18:59:21 UTC
fixed in mdb.master
fixed in 0.9.20
Comment 5 Quanah Gibson-Mount 2018-02-09 18:59:21 UTC
changed notes
changed state Test to Closed