Skip to content

\0 interpreted wrongly in cursor range (nodejs). #334

@mikelehen

Description

@mikelehen

I attempted to iterate all objects where the first element of the composite key is 'Johnson' by using the following index range (using 'Johnson\0' as the first entry that shouldn't match):

    const range = IDBKeyRange.bound(
      ['Johnson'],
      ['Johnson\0'],
      /*lowerOpen=*/ false, /*upperOpen=*/true
    );

This works as expected using native IndexedDb in a browser, but with indexeddbshim in node.js I get results like 'Johnson2 ...' that should be out of range. Based on the results I get, I think '\0' is being treated as '\...' or something (i.e. as a backslash instead of as a null character).

Repro code:


if (typeof process !== 'undefined') {
  const setGlobalVars = require('indexeddbshim');
  global.window = global;
  setGlobalVars(window, {checkOrigin: false, deleteDatabaseFiles: true});
}

const request = window.indexedDB.open("database", 1);
// Create schema
request.onupgradeneeded = event => {
    const db = event.target.result;
    
    const store = db.createObjectStore(
        "people",
        { keyPath: ["last", "first"] }
    );
};

request.onsuccess = event => {
  const db = request.result;
  const transaction = db.transaction(
      [ "people" ],
      "readwrite"
  );

  const mystore = transaction.objectStore("people");
  mystore.put({ last: 'Johnsom', first: 'NOPE' });
  mystore.put({ last: 'Johnson', first: 'Fred' });
  mystore.put({ last: 'Johnson', first: 'Sally' });
  mystore.put({ last: 'Johnson2', first: 'NOPE' });
  mystore.put({ last: 'Johnson\\', first: 'NOPE' });
  mystore.put({ last: 'Johnson]', first: 'NOPE' });

  transaction.oncomplete = () => {
    const transaction = db.transaction(
        [ "people" ],
        "readwrite"
    );
    const mystore = transaction.objectStore("people");
    
    // Now iterate people with lastname Johnson.
    const range = IDBKeyRange.bound(
      ['Johnson'],
      ['Johnson\0'],
      /*lowerOpen=*/ false, /*upperOpen=*/true
    );
    const request = mystore.openCursor(range, 'next');
    request.onsuccess = event => {
      const cursor = event.target.result;
      if (cursor) {
        console.log(cursor.value);
        cursor.continue();
      }
    };
  };
};

Result with native IndexedDb on Chrome, Firefox, and Safari:

{last: "Johnson", first: "Fred"}
{last: "Johnson", first: "Sally"}

Result with indexedDb in node:

{ last: 'Johnson', first: 'Fred' }
{ last: 'Johnson', first: 'Sally' }
{ last: 'Johnson2', first: 'NOPE' }
{ last: 'Johnson\\', first: 'NOPE' }

The last two entries shouldn't be there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions