fix unicode password length display

This commit is contained in:
Antelle 2016-01-16 17:19:33 +03:00
parent 5ee7d3800b
commit 9bc03634c5
9 changed files with 55 additions and 14 deletions

View File

@ -0,0 +1,39 @@
'use strict';
var kdbxweb = require('kdbxweb');
kdbxweb.ProtectedValue.prototype.isProtected = true;
Object.defineProperty(kdbxweb.ProtectedValue.prototype, 'textLength', {
get: function() {
var textLength = 0;
var value = this._value, salt = this._salt;
for (var i = 0, len = value.length; i < len; i++) {
var b = value[i] ^ salt[i];
if (b < 128) {
textLength++;
} else if (b >= 192 && b < 224 && i+1 < len) {
i++;
textLength++;
} else if (b >= 224 && b < 240 && i+2 < len) {
i += 2;
textLength++;
} else if (b >= 240 && b < 248 && i+3 < len) {
i++; var b1 = value[i] ^ salt[i];
i++; var b2 = value[i] ^ salt[i];
i++; var b3 = value[i] ^ salt[i];
var c = ((b & 7) << 18) | ((b1 & 0x3f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f);
if (c <= 0xffff) {
textLength++;
} else {
textLength += 2;
}
} else {
throw new Error('Malformed UTF8 character at byte offset ' + i);
}
}
return textLength;
}
});
module.exports = kdbxweb.ProtectedValue;

View File

@ -13,6 +13,7 @@ var Backbone = require('backbone'),
Storage = require('../storage'),
IdGenerator = require('../util/id-generator'),
Logger = require('../util/logger');
require('../mixins/protected-value-ex');
var AppModel = Backbone.Model.extend({
defaults: {},

View File

@ -222,7 +222,7 @@ var EntryModel = Backbone.Model.extend({
matchField: function(entry, field, compare, search) {
var val = entry.fields[field];
return val ? compare(val.getText ? val.getText() : val, search) : false;
return val ? compare(val.isProtected ? val.getText() : val, search) : false;
},
setColor: function(color) {
@ -259,7 +259,7 @@ var EntryModel = Backbone.Model.extend({
setField: function(field, val) {
this._entryModified();
var hasValue = val && (typeof val === 'string' || val instanceof kdbxweb.ProtectedValue && val.byteLength);
var hasValue = val && (typeof val === 'string' || val.isProtected && val.byteLength);
if (hasValue || this.builtInFields.indexOf(field) >= 0) {
this.entry.fields[field] = val;
} else {

View File

@ -300,7 +300,7 @@ var FileModel = Backbone.Model.extend({
setPassword: function(password) {
this.db.credentials.setPassword(password);
this.db.meta.keyChanged = new Date();
this.set({ passwordLength: password.byteLength, passwordChanged: true });
this.set({ passwordLength: password.textLength, passwordChanged: true });
this.setModified();
},

View File

@ -276,7 +276,7 @@ var DetailsView = Backbone.View.extend({
copyKeyPress: function() { // TODO: fix this in Safari
if (!window.getSelection().toString()) {
var pw = this.model.password;
var password = pw.getText ? pw.getText() : pw;
var password = pw.isProtected ? pw.getText() : pw;
CopyPaste.createHiddenInput(password);
var clipboardTime = CopyPaste.copied();
if (!this.passCopyTip) {

View File

@ -4,7 +4,7 @@ var FieldView = require('./field-view');
var FieldViewReadOnly = FieldView.extend({
renderValue: function(value) {
return typeof value.byteLength === 'number' ? new Array(value.byteLength + 1).join('•') : _.escape(value);
return value.isProtected ? new Array(value.textLength + 1).join('•') : _.escape(value);
},
readonly: true

View File

@ -10,12 +10,12 @@ var Backbone = require('backbone'),
var FieldViewText = FieldView.extend({
renderValue: function(value) {
return value && typeof value.byteLength === 'number' ? PasswordGenerator.present(value.byteLength) :
return value && value.isProtected ? PasswordGenerator.present(value.textLength) :
_.escape(value || '').replace(/\n/g, '<br/>');
},
getEditValue: function(value) {
return value && value.getText ? value.getText() : value || '';
return value && value.isProtected ? value.getText() : value || '';
},
startEdit: function() {

View File

@ -36,7 +36,7 @@ var FieldView = Backbone.View.extend({
var field = this.model.name;
if (FeatureDetector.shouldMoveHiddenInputToCopySource()) {
var box = this.valueEl[0].getBoundingClientRect();
var textValue = this.value && this.value.getText ? this.value.getText() : this.getEditValue(this.value);
var textValue = this.value && this.value.isProtected ? this.value.getText() : this.getEditValue(this.value);
if (!textValue) {
return;
}
@ -46,7 +46,7 @@ var FieldView = Backbone.View.extend({
}
if (field) {
var value = this.value || '';
if (value && value.getText) {
if (value && value.isProtected) {
CopyPaste.createHiddenInput(value.getText());
CopyPaste.tryCopy();
return;
@ -86,10 +86,10 @@ var FieldView = Backbone.View.extend({
return;
}
this.editing = false;
var oldValText = this.value && this.value.getText ? this.value.getText() : this.value;
var newValText = newVal && newVal.getText ? newVal.getText() : newVal;
var oldValText = this.value && this.value.isProtected ? this.value.getText() : this.value;
var newValText = newVal && newVal.isProtected ? newVal.getText() : newVal;
var textEqual = _.isEqual(newValText, oldValText);
var protectedEqual = (newVal && typeof newVal.getText) === (this.value && typeof this.value.getText);
var protectedEqual = (newVal && newVal.isProtected) === (this.value && this.value.isProtected);
var nameChanged = extra && extra.newField;
var arg;
if (newVal !== undefined && (!textEqual || !protectedEqual || nameChanged)) {

View File

@ -177,8 +177,9 @@ var ListSearchView = Backbone.View.extend({
}
var sortIconCls = this.sortIcons[filter.sort] || 'sort';
this.$el.find('.list__search-btn-sort>i').attr('class', 'fa fa-' + sortIconCls);
if (this.advancedSearchEnabled !== !!filter.filter.advanced) {
this.advancedSearchEnabled = !!filter.filter.advanced;
var adv = !!filter.filter.advanced;
if (this.advancedSearchEnabled !== adv) {
this.advancedSearchEnabled = adv;
this.$el.find('.list__search-adv').toggleClass('hide', !this.advancedSearchEnabled);
}
},