aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-02-17 19:43:44 -0500
committertoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-02-22 12:09:34 -0500
commit086fefc9215b0b4d2a63ad371b1e3302f32d725b (patch)
tree89f05ca158b8789c694d7d66a19d90009c90758a
parentd620f40448928d3bd3dc8bbafd95bedd177c9975 (diff)
Validate data before importing
-rw-r--r--ext/bg/js/database.js53
1 files changed, 46 insertions, 7 deletions
diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js
index f85ac7f3..c42b9d89 100644
--- a/ext/bg/js/database.js
+++ b/ext/bg/js/database.js
@@ -16,11 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/*global dictFieldSplit, JSZip*/
+/*global dictFieldSplit, requestJson, JsonSchema, JSZip*/
class Database {
constructor() {
this.db = null;
+ this._schemas = new Map();
}
// Public
@@ -332,6 +333,9 @@ class Database {
const index = JSON.parse(await indexFile.async('string'));
+ const indexSchema = await this._getSchema('/bg/data/dictionary-index-schema.json');
+ JsonSchema.validate(index, indexSchema);
+
const dictionaryTitle = index.title;
const version = index.format || index.version;
@@ -381,7 +385,7 @@ class Database {
};
// Archive file reading
- const readFileSequence = async (fileNameFormat, convertEntry) => {
+ const readFileSequence = async (fileNameFormat, convertEntry, schema) => {
const results = [];
for (let i = 1; true; ++i) {
const fileName = fileNameFormat.replace(/\?/, `${i}`);
@@ -389,6 +393,8 @@ class Database {
if (!file) { break; }
const entries = JSON.parse(await file.async('string'));
+ JsonSchema.validate(entries, schema);
+
for (let entry of entries) {
entry = convertEntry(entry);
entry.dictionary = dictionaryTitle;
@@ -398,12 +404,16 @@ class Database {
return results;
};
+ // Load schemas
+ const dataBankSchemaPaths = this.constructor._getDataBankSchemaPaths(version);
+ const dataBankSchemas = await Promise.all(dataBankSchemaPaths.map((path) => this._getSchema(path)));
+
// Load data
- const termList = await readFileSequence('term_bank_?.json', convertTermBankEntry);
- const termMetaList = await readFileSequence('term_meta_bank_?.json', convertTermMetaBankEntry);
- const kanjiList = await readFileSequence('kanji_bank_?.json', convertKanjiBankEntry);
- const kanjiMetaList = await readFileSequence('kanji_meta_bank_?.json', convertKanjiMetaBankEntry);
- const tagList = await readFileSequence('tag_bank_?.json', convertTagBankEntry);
+ const termList = await readFileSequence('term_bank_?.json', convertTermBankEntry, dataBankSchemas[0]);
+ const termMetaList = await readFileSequence('term_meta_bank_?.json', convertTermMetaBankEntry, dataBankSchemas[1]);
+ const kanjiList = await readFileSequence('kanji_bank_?.json', convertKanjiBankEntry, dataBankSchemas[2]);
+ const kanjiMetaList = await readFileSequence('kanji_meta_bank_?.json', convertKanjiMetaBankEntry, dataBankSchemas[3]);
+ const tagList = await readFileSequence('tag_bank_?.json', convertTagBankEntry, dataBankSchemas[4]);
// Old tags
const indexTagMeta = index.tagMeta;
@@ -487,6 +497,35 @@ class Database {
}
}
+ async _getSchema(fileName) {
+ let schemaPromise = this._schemas.get(fileName);
+ if (typeof schemaPromise !== 'undefined') {
+ return schemaPromise;
+ }
+
+ schemaPromise = requestJson(chrome.runtime.getURL(fileName), 'GET');
+ this._schemas.set(fileName, schemaPromise);
+ return schemaPromise;
+ }
+
+ static _getDataBankSchemaPaths(version) {
+ const termBank = (
+ version === 1 ?
+ '/bg/data/dictionary-term-bank-v1-schema.json' :
+ '/bg/data/dictionary-term-bank-v3-schema.json'
+ );
+ const termMetaBank = '/bg/data/dictionary-term-meta-bank-v3-schema.json';
+ const kanjiBank = (
+ version === 1 ?
+ '/bg/data/dictionary-kanji-bank-v1-schema.json' :
+ '/bg/data/dictionary-kanji-bank-v3-schema.json'
+ );
+ const kanjiMetaBank = '/bg/data/dictionary-kanji-meta-bank-v3-schema.json';
+ const tagBank = '/bg/data/dictionary-tag-bank-v3-schema.json';
+
+ return [termBank, termMetaBank, kanjiBank, kanjiMetaBank, tagBank];
+ }
+
async _dictionaryExists(title) {
const db = this.db;
const dbCountTransaction = db.transaction(['dictionaries'], 'readonly');