diff options
Diffstat (limited to 'source/import/Aegis.mc')
| -rw-r--r-- | source/import/Aegis.mc | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/source/import/Aegis.mc b/source/import/Aegis.mc index 05905e9..0d515cd 100644 --- a/source/import/Aegis.mc +++ b/source/import/Aegis.mc @@ -4,7 +4,8 @@ // README 11.3. The reader consumes the token stream of Json.Tokenizer and // tracks the path of the current value ("/db/entries/[]/info/secret"), so it // can stop after any token and continue in the next event. It keeps only -// the parsed items and the group names, never the document. +// the parsed items (packed, see ImportItem) and the group names; the +// document's bytes stay with the tokenizer. // // * Encrypted exports are refused: header.slots is not null, or db is a // string. @@ -34,7 +35,10 @@ class AegisReader { static const ENCRYPTED_MESSAGE = "This Aegis export is encrypted. In Aegis choose Export, then turn encryption off, and paste that file."; - var items as Array<ImportItem> = [] as Array<ImportItem>; + // Parsed items, packed (ImportItem.pack); unpack with item(i). + var items as Array<ByteArray> = [] as Array<ByteArray>; + // Group UUID -> name, from db.groups. + var groups as Dictionary<String, String> = {} as Dictionary<String, String>; var error as String? = null; private var _tok as Json.Tokenizer; @@ -44,7 +48,6 @@ class AegisReader { private var _fields as ImportFields? = null; private var _seen as Dictionary<String, Boolean> = {} as Dictionary<String, Boolean>; private var _group as Dictionary<String, String>? = null; - private var _groups as Dictionary<String, String> = {} as Dictionary<String, String>; private var _encrypted as Boolean = false; private var _vaultVersion as Long = -1l; private var _sawEntries as Boolean = false; @@ -53,11 +56,25 @@ class AegisReader { _tok = new Json.Tokenizer(data); } - // Bytes read so far (for progress). + // Bytes read so far, and in all (for progress). function position() as Number { return _tok.pos; } + function size() as Number { + return _tok.size(); + } + + // The document's bytes (saved when it is incomplete). + function data() as ByteArray { + return _tok.data(); + } + + // Parsed item i, unpacked, with its group name resolved. + function item(i as Number) as ImportItem { + return ImportItem.unpack(items[i], groups); + } + // Process up to TOKENS_PER_STEP tokens. Returns RUNNING, DONE, // INCOMPLETE (the text ends early: wait for more) or FAILED (error set). function step() as Number { @@ -139,14 +156,14 @@ class AegisReader { item.label = fields.issuer.length() > 0 ? fields.issuer : fields.account; } fields.secret = null; - items.add(item); + items.add(item.pack()); } _item = null; _fields = null; } else if (p.equals("/db/groups/[]")) { var g = _group; if (g != null && g.hasKey("uuid") && g.hasKey("name")) { - _groups[g["uuid"] as String] = g["name"] as String; + groups[g["uuid"] as String] = g["name"] as String; } _group = null; } @@ -244,19 +261,8 @@ class AegisReader { return fail(_vaultVersion > 1 ? "Aegis export version " + _vaultVersion + " is not supported" : "not an Aegis export (no version 1 vault with db.entries)"); } - // Resolve group references now that db.groups has been read. - for (var i = 0; i < items.size(); i++) { - var item = items[i]; - var ref = item.groupRef; - var e = item.entry; - if (ref == null || e == null) { - continue; - } - var name = ref.find("uuid:") == 0 ? _groups[ref.substring(5, ref.length()) as String] : ref.substring(5, ref.length()); - if (name != null) { - e.group = fitBytes(Text.trim(name as String), Entry.MAX_GROUP_BYTES); - } - } + // Group references are resolved when items are unpacked (db.groups + // may come after the entries). return DONE; } |
