Skip to content

Commit

Permalink
- Enhancement (for data integrity): Add default option
Browse files Browse the repository at this point in the history
    `normalizeDatabaseNames` to escape characters that expand on NFD
    normalization so as to avoid accidental loss of Unicode expression and
    potential name clashes on MacOS which does NFD normalization on the file
    system (user should normalize themselves if they want normalization);
    part of indexeddbshim#278
  • Loading branch information
brettz9 committed Apr 8, 2017
1 parent 3c33658 commit 808ca65
Show file tree
Hide file tree
Showing 19 changed files with 396 additions and 246 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ they were actually changes since a more recent version on `master`.
- Enhancement: Add `deleteDatabaseFiles` config to allow file itself to
be deleted in Node; will throw `UnknownError` if there are any errors
removing file (besides a missing file)
- Enhancement (for data integrity): Add default option
`normalizeDatabaseNames` to escape characters that expand on NFD
normalization so as to avoid accidental loss of Unicode expression and
potential name clashes on MacOS which does NFD normalization on the file
system (user should normalize themselves if they want normalization);
part of #278
- Add missing API: Add `IDBCursor.continuePrimaryKey`
- Add missing API: Implement `IDBObjectStore.getKey`
- Add missing APIs: Implement `IDBIndex.getAll/getAllKeys`
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,11 @@ browser, particularly if one changes the defaults.
the escaped filename exceeds the length of 254 characters (the shortest
typical modern file length maximum). Provide a number to change the
limit or supply `false` to disable any length checking.
- __escapeNFDForDatabaseNames__ - Boolean defaulting to true on whether
to escape NFD-escaping characters to avoid clashes on MacOS which
performs NFD on files
- __addSQLiteExtension__ - Boolean on whether to add the `.sqlite` extension
to file names; defaults to `true`

The following config items are for Node only and are mostly for development
debugging.
Expand Down
105 changes: 64 additions & 41 deletions dist/indexeddbshim-UnicodeIdentifiers-node.js

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions dist/indexeddbshim-UnicodeIdentifiers-node.min.js

Large diffs are not rendered by default.

103 changes: 63 additions & 40 deletions dist/indexeddbshim-UnicodeIdentifiers.js

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions dist/indexeddbshim-UnicodeIdentifiers.min.js

Large diffs are not rendered by default.

103 changes: 63 additions & 40 deletions dist/indexeddbshim-node.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions dist/indexeddbshim-node.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/indexeddbshim-node.min.js.map

Large diffs are not rendered by default.

99 changes: 61 additions & 38 deletions dist/indexeddbshim-noninvasive.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions dist/indexeddbshim-noninvasive.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/indexeddbshim-noninvasive.min.js.map

Large diffs are not rendered by default.

101 changes: 62 additions & 39 deletions dist/indexeddbshim.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions dist/indexeddbshim.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/indexeddbshim.min.js.map

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"sync-promise": "https://github.com/brettz9/sync-promise#full-sync-missing-promise-features",
"typeson": "https://github.com/dfahlander/typeson",
"typeson-registry": "https://github.com/dfahlander/typeson-registry",
"unicode-9.0.0": "0.7.0",
"w3c-blob": "0.0.1",
"ws": "2.2.2",
"xmlhttprequest": "https://github.com/brettz9/node-XMLHttpRequest#local-and-prototype"
Expand Down
33 changes: 19 additions & 14 deletions src/CFG.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ const CFG = {};
// Boolean for verbose reporting
'DEBUG', // Effectively defaults to false (ignored unless `true`)

// Used when setting global shims to determine whether to try to add
// other globals shimmed by the library (`ShimDOMException`, `ShimDOMStringList`,
// `ShimEvent`, `ShimCustomEvent`, `ShimEventTarget`)
'addNonIDBGlobals', // Effectively defaults to false (ignored unless `true`)

// Determines whether the slow-performing `Object.setPrototypeOf` calls required
// for full WebIDL compliance will be used. Probably only needed for testing
// or environments where full introspection on class relationships is required;
Expand All @@ -29,14 +24,6 @@ const CFG = {};
'UnicodeIDStart', // In the non-Unicode builds, defaults to /[$A-Z_a-z]/
'UnicodeIDContinue', // In the non-Unicode builds, defaults to /[$0-9A-Z_a-z]/

// NODE-SPECIFIC CONFIG
// Boolean on whether to delete the database file itself after `deleteDatabase`;
// defaults to `true` as the database will be empty
'deleteDatabaseFiles',
// Boolean on whether to add the `.sqlite` extension to file names;
// defaults to `true`
'addSQLiteExtension',

// -----------SQL CONFIG----------
// Object (`window` in the browser) on which there may be an
// `openDatabase` method (if any) for WebSQL. (The browser
Expand All @@ -56,6 +43,14 @@ const CFG = {};
// quota every five megabytes."
'DEFAULT_DB_SIZE', // Defaults to (4 * 1024 * 1024) or (25 * 1024 * 1024) in Safari

// NODE-IMPINGING SETTINGS (created for sake of limitations in Node or desktop file
// system implementation but applied by default in browser for parity)

// Used when setting global shims to determine whether to try to add
// other globals shimmed by the library (`ShimDOMException`, `ShimDOMStringList`,
// `ShimEvent`, `ShimCustomEvent`, `ShimEventTarget`)
'addNonIDBGlobals', // Effectively defaults to false (ignored unless `true`)

// Overcoming limitations with node-sqlite3/storing database name on file systems
// https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
'escapeDatabaseName', // Defaults to prefixing database with `D_`, escaping
Expand All @@ -67,8 +62,18 @@ const CFG = {};
// (characters nevertheless commonly reserved in modern, Unicode-supporting
// systems): 0x00-0x1F 0x7F " * / : < > ? \ |
'databaseNameLengthLimit', // Defaults to 254 (shortest typical modern file length limit)
'escapeNFDForDatabaseNames', // Boolean defaulting to true on whether to escape NFD-escaping
// characters to avoid clashes on MacOS which performs NFD on files
// Boolean on whether to add the `.sqlite` extension to file names;
// defaults to `true`
'addSQLiteExtension',

// NODE-SPECIFIC CONFIG
// Boolean on whether to delete the database file itself after `deleteDatabase`;
// defaults to `true` as the database will be empty
'deleteDatabaseFiles',

// Optional Node WebSQL config
// NODE-SPECIFIC WEBSQL CONFIG
'sqlBusyTimeout', // Defaults to 1000
'sqlTrace', // Callback not used by default
'sqlProfile' // Callback not used by default
Expand Down
21 changes: 16 additions & 5 deletions src/util.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import CFG from './CFG';
import expandsOnNFD from 'unicode-9.0.0/Binary_Property/Expands_On_NFD/regex';

function escapeNameForSQLiteIdentifier (arg) {
// http://stackoverflow.com/a/6701665/271577
Expand Down Expand Up @@ -48,6 +49,12 @@ function escapeDatabaseNameForSQLAndFiles (db) {
return CFG.escapeDatabaseName(escapeSQLiteStatement(db));
}
db = 'D' + escapeNameForSQLiteIdentifier(db);
if (CFG.escapeNFDForDatabaseNames !== false) {
// ES6 copying of regex with different flags
db = db.replace(new RegExp(expandsOnNFD, 'g'), function (expandable) {
return '^4' + expandable.codePointAt().toString(16).padStart(6, '0');
});
}
if (CFG.databaseCharacterEscapeList !== false) {
db = db.replace(
(CFG.databaseCharacterEscapeList
Expand Down Expand Up @@ -78,11 +85,15 @@ function unescapeDatabaseNameForSQLAndFiles (db) {
}

return db.slice(2) // D_
.replace(/(\^+)1([0-9a-f]{2})/g, (_, esc, hex) => esc % 2 ? String.fromCharCode(parseInt(hex, 16)) : _) // databaseCharacterEscapeList
.replace(/(\^+)3\uD800([\uDC00-\uDFFF])/g, (_, esc, lowSurr) => esc % 2 ? lowSurr : _)
.replace(/(\^+)2([\uD800-\uDBFF])\uDC00/g, (_, esc, highSurr) => esc % 2 ? highSurr : _)
.replace(/(\^+)([A-Z])/g, (_, esc, upperCase) => esc % 2 ? upperCase : _)
.replace(/(\^+)0/g, (_, esc) => esc % 2 ? '\0' : _)
// CFG.databaseCharacterEscapeList
.replace(/(\^+)1([0-9a-f]{2})/g, (_, esc, hex) => esc.length % 2 ? String.fromCharCode(parseInt(hex, 16)) : _)
// CFG.escapeNFDForDatabaseNames
.replace(/(\^+)4([0-9a-f]{6})/g, (_, esc, hex) => esc.length % 2 ? String.fromCodePoint(parseInt(hex, 16)) : _)
// escapeNameForSQLiteIdentifier
.replace(/(\^+)3\uD800([\uDC00-\uDFFF])/g, (_, esc, lowSurr) => esc.length % 2 ? lowSurr : _)
.replace(/(\^+)2([\uD800-\uDBFF])\uDC00/g, (_, esc, highSurr) => esc.length % 2 ? highSurr : _)
.replace(/(\^+)([A-Z])/g, (_, esc, upperCase) => esc.length % 2 ? upperCase : _)
.replace(/(\^+)0/g, (_, esc) => esc.length % 2 ? '\0' : _)
.replace(/\^\^/g, '^');
}

Expand Down

0 comments on commit 808ca65

Please sign in to comment.