Skip to content

Commit

Permalink
- Fix (for data integrity on Node): Add default option `normalizeData…
Browse files Browse the repository at this point in the history
…baseNames` 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 672fd79
Show file tree
Hide file tree
Showing 18 changed files with 390 additions and 246 deletions.
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 672fd79

Please sign in to comment.