1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

Render personal_sign messages as utf-8 text

Calls to `personal_sign` are now:

- When hex encoded, preserved as hex encoded, but displayed as utf-8 text.
- When not hex encoded, decoded as utf-8 text as hex for signing.
- The messages proposed for signing are displayed as UTF-8 text.
- When the message cannot be rendered as UTF-8 text, it is displayed as hexadecimal.

Fixes #1173
This commit is contained in:
Dan Finlay 2017-03-06 15:03:49 -08:00
parent f9b2c12dc3
commit 9bd8c5f723
5 changed files with 107 additions and 21 deletions

View File

@ -2,6 +2,7 @@ const EventEmitter = require('events')
const ObservableStore = require('obs-store') const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const createId = require('./random-id') const createId = require('./random-id')
const hexRe = /^[0-9A-Fa-f]+$/g
module.exports = class PersonalMessageManager extends EventEmitter{ module.exports = class PersonalMessageManager extends EventEmitter{
@ -24,7 +25,8 @@ module.exports = class PersonalMessageManager extends EventEmitter{
} }
addUnapprovedMessage (msgParams) { addUnapprovedMessage (msgParams) {
msgParams.data = normalizeMsgData(msgParams.data) log.debug(`PersonalMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`)
msgParams.data = this.normalizeMsgData(msgParams.data)
// create txData obj with parameters and meta data // create txData obj with parameters and meta data
var time = (new Date()).getTime() var time = (new Date()).getTime()
var msgId = createId() var msgId = createId()
@ -106,14 +108,18 @@ module.exports = class PersonalMessageManager extends EventEmitter{
this.emit('updateBadge') this.emit('updateBadge')
} }
normalizeMsgData(data) {
try {
const stripped = ethUtil.stripHexPrefix(data)
if (stripped.match(hexRe)) {
return stripped
}
} catch (e) {
log.debug(`Message was not hex encoded, interpreting as utf8.`)
} }
function normalizeMsgData(data) {
if (data.slice(0, 2) === '0x') {
// data is already hex
return data
} else {
// data is unicode, convert to hex
return ethUtil.bufferToHex(new Buffer(data, 'utf8')) return ethUtil.bufferToHex(new Buffer(data, 'utf8'))
} }
} }

View File

@ -0,0 +1,25 @@
var assert = require('assert')
var BinaryRenderer = require('../../../ui/app/components/binary-renderer')
describe('BinaryRenderer', function() {
let binaryRenderer
const message = 'Hello, world!'
const buffer = new Buffer(message, 'utf8')
const hex = buffer.toString('hex')
beforeEach(function() {
binaryRenderer = new BinaryRenderer()
})
it('recovers message', function() {
const result = binaryRenderer.hexToText(hex)
assert.equal(result, message)
})
it('recovers message with hex prefix', function() {
const result = binaryRenderer.hexToText('0x' + hex)
assert.equal(result, message)
})
})

View File

@ -4,7 +4,7 @@ const EventEmitter = require('events')
const PersonalMessageManager = require('../../app/scripts/lib/personal-message-manager') const PersonalMessageManager = require('../../app/scripts/lib/personal-message-manager')
describe('Transaction Manager', function() { describe('Personal Message Manager', function() {
let messageManager let messageManager
beforeEach(function() { beforeEach(function() {
@ -86,4 +86,25 @@ describe('Transaction Manager', function() {
assert.equal(messageManager.getMsg('2').status, 'approved') assert.equal(messageManager.getMsg('2').status, 'approved')
}) })
}) })
describe('#normalizeMsgData', function() {
it('converts text to a utf8 buffer', function() {
var input = 'hello'
var output = messageManager.normalizeMsgdata(input)
assert.equal(output, '68656c6c6f', 'predictably hex encoded')
})
it('tolerates a hex prefix', function() {
var input = '0x12'
var output = messageManager.normalizeMsgdata(input)
assert.equal(output, '12', 'prefix stripped')
})
it('tolerates normal hex', function() {
var input = '12'
var output = messageManager.normalizeMsgdata(input)
assert.equal(output, '12', 'not modified')
})
})
}) })

View File

@ -0,0 +1,43 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const ethUtil = require('ethereumjs-util')
module.exports = BinaryRenderer
inherits(BinaryRenderer, Component)
function BinaryRenderer () {
Component.call(this)
}
BinaryRenderer.prototype.render = function () {
const props = this.props
const { value } = props
const text = this.hexToText(value)
return (
h('textarea.font-small', {
readOnly: true,
style: {
width: '315px',
maxHeight: '210px',
resize: 'none',
border: 'none',
background: 'white',
padding: '3px',
},
defaultValue: text,
})
)
}
BinaryRenderer.prototype.hexToText = function (hex) {
try {
const stripped = ethUtil.stripHexPrefix(hex)
const buff = Buffer.from(stripped, 'hex')
return buff.toString('utf8')
} catch (e) {
return hex
}
}

View File

@ -3,6 +3,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits const inherits = require('util').inherits
const AccountPanel = require('./account-panel') const AccountPanel = require('./account-panel')
const BinaryRenderer = require('./binary-renderer')
module.exports = PendingMsgDetails module.exports = PendingMsgDetails
@ -21,6 +22,7 @@ PendingMsgDetails.prototype.render = function () {
var account = state.accounts[address] || { address: address } var account = state.accounts[address] || { address: address }
var { data } = msgParams var { data } = msgParams
console.dir({ msgParams })
return ( return (
h('div', { h('div', {
@ -41,18 +43,7 @@ PendingMsgDetails.prototype.render = function () {
// message data // message data
h('div', [ h('div', [
h('label.font-small', { style: { display: 'block' } }, 'MESSAGE'), h('label.font-small', { style: { display: 'block' } }, 'MESSAGE'),
h('textarea.font-small', { h(BinaryRenderer, { value: data }),
readOnly: true,
style: {
width: '315px',
maxHeight: '210px',
resize: 'none',
border: 'none',
background: 'white',
padding: '3px',
},
defaultValue: data,
}),
]), ]),
]) ])