diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d400b66..f2c442050 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Current Master +- Add a check for improper Transaction data. + ## 2.13.5 2016-10-18 - Increase default max gas to `100000` over the RPC's `estimateGas` response. diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js index c6bfdb4da..052a8f5fe 100644 --- a/app/scripts/lib/inpage-provider.js +++ b/app/scripts/lib/inpage-provider.js @@ -84,7 +84,7 @@ MetamaskInpageProvider.prototype.send = function (payload) { // throw not-supported Error default: var link = 'https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client' - var message = `The MetaMask Web3 object does not support synchronous methods like ${payload.method}. See ${link} for details.` + var message = `The MetaMask Web3 object does not support synchronous methods like ${payload.method} without a callback parameter. See ${link} for details.` throw new Error(message) } diff --git a/test/unit/util_test.js b/test/unit/util_test.js index 45e545e8e..00528b905 100644 --- a/test/unit/util_test.js +++ b/test/unit/util_test.js @@ -227,5 +227,27 @@ describe('util', function() { assert.equal(result.toString(10), '1111000000000000000', 'accepts decimals') }) }) + describe('#isHex', function(){ + it('should return true when given a hex string', function() { + var result = util.isHex('c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2') + assert(result) + }) + + it('should return false when given a non-hex string', function() { + var result = util.isHex('c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714imnotreal') + assert(!result) + }) + + it('should return false when given a string containing a non letter/number character', function() { + var result = util.isHex('c3ab8ff13720!8ad9047dd39466b3c%8974e592c2fa383d4a396071imnotreal') + assert(!result) + }) + + it('should return true when given a hex string with hex-prefix', function() { + var result = util.isHex('0xc3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2') + assert(result) + }) + + }) }) }) diff --git a/ui/app/send.js b/ui/app/send.js index 97ed29e4a..b8af19028 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -7,6 +7,7 @@ const actions = require('./actions') const util = require('./util') const numericBalance = require('./util').numericBalance const addressSummary = require('./util').addressSummary +const isHex = require('./util').isHex const EthBalance = require('./components/eth-balance') const ethUtil = require('ethereumjs-util') const RangeSlider = require('./components/range-slider') @@ -190,7 +191,7 @@ SendTransactionScreen.prototype.render = function () { marginBottom: '16px', }, }, [ - 'Transactional Data (optional)', + 'Transaction Data (optional)', ]), // 'data' field @@ -312,6 +313,11 @@ SendTransactionScreen.prototype.onSubmit = function (gasPrice) { return this.props.dispatch(actions.displayWarning(message)) } + if (!isHex(ethUtil.stripHexPrefix(txData)) && txData) { + message = 'Transaction data must be hex string.' + return this.props.dispatch(actions.displayWarning(message)) + } + this.props.dispatch(actions.hideWarning()) var txParams = { diff --git a/ui/app/util.js b/ui/app/util.js index e4b77e2bc..7a56bf6a0 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -35,6 +35,7 @@ module.exports = { normalizeNumberToWei: normalizeNumberToWei, valueTable: valueTable, bnTable: bnTable, + isHex: isHex, } function valuesFor (obj) { @@ -209,3 +210,7 @@ function readableDate (ms) { var time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}` return `${dateStr} ${time}` } + +function isHex (str) { + return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/)) +}