diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 3f523717..e6f111a6 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,9 @@ +2024-12-20 David Declerck + + * fileio.c (indexed_start_internal): improve handling of partial + keys, to ensure BDB always compares keys of identical length + 2024-12-18 David Declerck * string.c: fix a bug where the source of STRING/UNSTRING/INSPECT diff --git a/libcob/fileio.c b/libcob/fileio.c index df7cc89c..26cde85a 100644 --- a/libcob/fileio.c +++ b/libcob/fileio.c @@ -923,6 +923,9 @@ bdb_bt_compare (DB *db, const DBT *k1, const DBT *k2 { const unsigned char *col = (unsigned char *)DBT_GET_APP_DATA (k1); COB_UNUSED (db); +#if DB_VERSION_MAJOR >= 6 + locp = NULL; /* docs: must be set to NULL or corruption can occur ... */ +#endif #ifdef USE_BDB_KEYDIFF /* flag passed with CPPFLAGS */ return cob_cmp_strings (k1->data, k2->data, (size_t)k1->size, (size_t)k2->size, col); #else @@ -936,9 +939,6 @@ bdb_bt_compare (DB *db, const DBT *k1, const DBT *k2 cob_hard_failure (); } /* LCOV_EXCL_STOP */ -#if DB_VERSION_MAJOR >= 6 - locp = NULL; /* docs: must be set to NULL or corruption can occur ... */ -#endif return indexed_key_compare (k1->data, k2->data, k2->size, col); #endif /* USE_BDB_KEYDIFF */ } @@ -3909,7 +3909,10 @@ indexed_start_internal (cob_file *f, const int cond, cob_field *key, /* Search */ bdb_setkey (f, p->key_index); - p->key.size = (cob_dbtsize_t)partlen; /* may be partial key */ + if (partlen < fullkeylen) { + memset((char *)p->key.data + partlen, 0, fullkeylen - partlen); + } + /* The open cursor makes this function atomic */ if (p->key_index != 0) { p->db[0]->cursor (p->db[0], NULL, &p->cursor[0], 0); diff --git a/tests/testsuite.src/run_file.at b/tests/testsuite.src/run_file.at index 9dca167e..6d97f578 100644 --- a/tests/testsuite.src/run_file.at +++ b/tests/testsuite.src/run_file.at @@ -3098,6 +3098,64 @@ rewriting key: 98651234 AT_CLEANUP +AT_SETUP([INDEXED START with partial key and collating sequence]) +AT_KEYWORDS([runfile READ WRITE START]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT F-DATA ASSIGN TO EXTERNAL fdata + ORGANIZATION INDEXED + ACCESS MODE DYNAMIC + RECORD KEY R-KEY + FILE STATUS F-STATUS. + DATA DIVISION. + FILE SECTION. + FD F-DATA. + 01 R-DATA. + 05 R-KEY. + 10 R-SUBKEY-1 PIC X(3). + 10 R-SUBKEY-2 PIC X(2). + 05 R-NUM PIC 99. + WORKING-STORAGE SECTION. + 01 F-STATUS PIC X(2) VALUE SPACE. + PROCEDURE DIVISION. + OPEN OUTPUT F-DATA. + MOVE "ABC12" TO R-KEY. + MOVE 1 TO R-NUM. + WRITE R-DATA. + MOVE "DEF34" TO R-KEY. + MOVE 2 TO R-NUM. + WRITE R-DATA. + MOVE "GHI56" TO R-KEY. + MOVE 3 TO R-NUM. + WRITE R-DATA. + CLOSE F-DATA. + OPEN INPUT F-DATA. + MOVE SPACES TO R-KEY. + MOVE "DEF" TO R-SUBKEY-1. + START F-DATA KEY >= R-SUBKEY-1. + DISPLAY "START STATUS: " F-STATUS. + READ F-DATA NEXT. + DISPLAY "READ STATUS: " F-STATUS. + DISPLAY "READ " R-KEY ", " R-NUM. + CLOSE F-DATA. + STOP RUN. +]) + +AT_CHECK([$COMPILE -fdefault-file-colseq=EBCDIC prog.cob], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], +[START STATUS: 00 +READ STATUS: 00 +READ DEF34, 02 +], []) + +AT_CLEANUP + + AT_SETUP([WRITE + REWRITE FILE name]) AT_KEYWORDS([runfile RELATIVE COB_SYNC])