Skip to content

Commit 7339a45

Browse files
committed
warn when importing incomptible sites
(v1 multibyte site names)
1 parent 78b65ee commit 7339a45

File tree

2 files changed

+102
-2
lines changed

2 files changed

+102
-2
lines changed

ext/data/config.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ function read_mpsites(d){
110110
lastused: s[1],
111111
timesused: s[2],
112112
passtype: s[3],
113-
passalgo: s[4],
114-
passcnt: s[5],
113+
passalgo: parseInt(s[4],10),
114+
passcnt: parseInt(s[5],10),
115115
loginname: s[6],
116116
sitename: s[7],
117117
sitepass: s[8]
@@ -192,6 +192,7 @@ $(document).on('drop', function(e){
192192
}
193193
var fr = new FileReader();
194194
fr.onload=function(x){
195+
var has_ver1_mb_sites = false;
195196
try {
196197
x = read_mpsites(x.target.result);
197198
if (!x) return;
@@ -217,6 +218,9 @@ $(document).on('drop', function(e){
217218
this.passcnt,
218219
this.passalgo);
219220

221+
if (this.passalgo < 2 && !string_is_plain_ascii(this.sitename))
222+
has_ver1_mb_sites = true;
223+
220224
if (! (this.sitesearch in stored_sites)) stored_sites[this.sitesearch] = {};
221225
stored_sites[this.sitesearch][this.sitename] = {
222226
'generation': this.passcnt,
@@ -225,6 +229,12 @@ $(document).on('drop', function(e){
225229
};
226230
});
227231

232+
if (has_ver1_mb_sites)
233+
alert("Version mismatch\n\nYour file contains site names with non ascii characters from "+
234+
"an old masterpassword version. This addon can not reproduce these passwords");
235+
else
236+
console.debug('Import successful');
237+
228238
save_sites_to_backend();
229239
};
230240
fr.readAsText(e.originalEvent.dataTransfer.files[0]);

ext/test/test-main.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,96 @@ exports["test main"] = function(assert) {
99
// if (require("sdk/system/runtime").OS == 'Linux') {
1010
// }
1111

12+
13+
function mpsites_upload_jquery() {
14+
return {
15+
on: function(x, cb){
16+
if (x === 'drop') {
17+
cb({
18+
originalEvent: {
19+
dataTransfer: {files:[{name:'test.mpsites'}]}
20+
},
21+
preventDefault: function(){},
22+
stopPropagation: function(){}
23+
});
24+
}
25+
},
26+
append: function(){}
27+
};
28+
}
29+
mpsites_upload_jquery.each = function(ar, cb) {
30+
for (var x in ar) {
31+
if (!ar.hasOwnProperty(x)) continue;
32+
cb.apply(ar[x], [x, ar[x]]);
33+
}
34+
};
35+
36+
exports["test mpsites upload invalid"] = function(assert) {
37+
var self = require("sdk/self");
38+
const { sandbox, evaluate, load } = require("sdk/loader/sandbox");
39+
var got_alert_not_mpsites = false;
40+
var scope = sandbox();
41+
scope.window = {
42+
'addEventListener': function(){}
43+
};
44+
scope.document = {};
45+
scope.console = console;
46+
scope.confirm = function(m){return true;};
47+
scope.alert = function(m){if (/Not a mpsites.file/.test(m)) got_alert_not_mpsites = true;};
48+
scope.$ = mpsites_upload_jquery;
49+
scope.FileReader = function() { this.onload = function(){ console.error('test failed, onload should be set!');}; };
50+
scope.FileReader.prototype.readAsText = function(){
51+
this.onload({target:{result:"invalid..not.a.mpsites.file"}});
52+
};
53+
load(scope, self.data.url('config.js'));
54+
55+
assert.ok(got_alert_not_mpsites);
56+
};
57+
58+
exports["test mpsites upload valid"] = function(assert) {
59+
var self = require("sdk/self");
60+
const { sandbox, evaluate, load } = require("sdk/loader/sandbox");
61+
62+
var file = [ '# Master Password site export',
63+
'# Export of site names and stored passwords (unless device-private) encrypted with the master key.',
64+
'# ', '##', '# Format: 1', '# Date: 2015-09-30T10:15:25Z', '# User Name: test', '# Full Name: test',
65+
'# Avatar: 0',
66+
'# Version: 2.2', '# Algorithm: 3', '# Default Type: 17', '# Passwords: PROTECTED',
67+
'##', '#',
68+
'# Last Times Password Login\t Site\tSite',
69+
'# used used type name\t name\tpassword',
70+
'2015-09-30T10:14:31Z 0 16:1:6 \t asite\t',
71+
'2015-09-30T10:14:39Z 0 18:1:4 \t åsite\t'
72+
].join('\n');
73+
74+
var version_mismatch_received = false;
75+
var event_received;
76+
var scope = sandbox();
77+
scope.window = {
78+
'addEventListener': function(){}
79+
};
80+
scope.document = {
81+
createEvent:function(){return{initCustomEvent:function(){ this.sites = arguments[3];}};},
82+
documentElement:{dispatchEvent: function(e){event_received=e;}}
83+
};
84+
scope.console = console;
85+
scope.confirm = function(m){return true;};
86+
scope.alert = function(m){ if (/Version mismatch/.test(m)) version_mismatch_received=true; } ;
87+
scope.$ = mpsites_upload_jquery;
88+
scope.FileReader = function() { this.onload = function(){ console.error('test failed, onload should be set!');}; };
89+
scope.FileReader.prototype.readAsText = function(){
90+
this.onload({target:{result:file}});
91+
};
92+
load(scope, self.data.url('config.js'));
93+
assert.ok(version_mismatch_received);
94+
assert.ok('asite' in event_received.sites);
95+
assert.ok('åsite' in event_received.sites);
96+
assert.equal(event_received.sites.asite.asite.generation, 6);
97+
assert.equal(event_received.sites.asite.asite.type, 'x');
98+
assert.equal(event_received.sites['åsite']['åsite'].generation, 4);
99+
assert.equal(event_received.sites['åsite']['åsite'].type, 'm');
100+
};
101+
12102
exports["test main handlers"] = function(assert, async_test_done) {
13103
var self = require("sdk/self");
14104
const { sandbox, evaluate, load } = require("sdk/loader/sandbox");

0 commit comments

Comments
 (0)