mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 20:25:48 +00:00
Check unknown serialization fields
This commit is contained in:
@@ -224,7 +224,9 @@ var base = [
|
||||
[ 'Fee' , REQUIRED ],
|
||||
[ 'OperationLimit' , OPTIONAL ],
|
||||
[ 'SigningPubKey' , REQUIRED ],
|
||||
[ 'TxnSignature' , OPTIONAL ]
|
||||
[ 'TxnSignature' , OPTIONAL ],
|
||||
[ 'AccountTxnID' , OPTIONAL ],
|
||||
[ 'Memos' , OPTIONAL ]
|
||||
];
|
||||
|
||||
exports.tx = {
|
||||
|
||||
@@ -97,39 +97,60 @@ SerializedObject.from_json = function(obj) {
|
||||
}
|
||||
|
||||
// ND: This from_*json* seems a reasonable place to put validation of `json`
|
||||
SerializedObject.check_no_missing_fields(typedef, obj);
|
||||
SerializedObject.check_fields(typedef, obj);
|
||||
so.serialize(typedef, obj);
|
||||
|
||||
return so;
|
||||
};
|
||||
|
||||
SerializedObject.check_no_missing_fields = function(typedef, obj) {
|
||||
var missing_fields = [];
|
||||
SerializedObject.check_fields = function(typedef, obj) {
|
||||
let missingFields = [];
|
||||
let unknownFields = [];
|
||||
let fieldsMap = {};
|
||||
|
||||
for (var i = typedef.length - 1; i >= 0; i--) {
|
||||
var spec = typedef[i];
|
||||
var field = spec[0];
|
||||
var requirement = spec[1];
|
||||
// Get missing required fields
|
||||
typedef.forEach(function(field) {
|
||||
var fieldName = field[0];
|
||||
var isRequired = field[1] === binformat.REQUIRED;
|
||||
|
||||
if (binformat.REQUIRED === requirement && obj[field] === undefined) {
|
||||
missing_fields.push(field);
|
||||
if (isRequired && obj[fieldName] === undefined) {
|
||||
missingFields.push(fieldName);
|
||||
} else {
|
||||
fieldsMap[fieldName] = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Get fields that are not specified in format
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
if (!fieldsMap[key] && /^[A-Z]/.test(key)) {
|
||||
unknownFields.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
if (!(missingFields.length || unknownFields.length)) {
|
||||
// No missing or unknown fields
|
||||
return;
|
||||
}
|
||||
|
||||
if (missing_fields.length > 0) {
|
||||
var object_name;
|
||||
var errorMessage;
|
||||
|
||||
if (obj.TransactionType !== undefined) {
|
||||
object_name = SerializedObject.lookup_type_tx(obj.TransactionType);
|
||||
errorMessage = SerializedObject.lookup_type_tx(obj.TransactionType);
|
||||
} else if (obj.LedgerEntryType !== undefined) {
|
||||
object_name = SerializedObject.lookup_type_le(obj.LedgerEntryType);
|
||||
errorMessage = SerializedObject.lookup_type_le(obj.LedgerEntryType);
|
||||
} else {
|
||||
object_name = 'TransactionMetaData';
|
||||
errorMessage = 'TransactionMetaData';
|
||||
}
|
||||
|
||||
throw new Error(object_name + ' is missing fields: ' +
|
||||
JSON.stringify(missing_fields));
|
||||
if (missingFields.length > 0) {
|
||||
errorMessage += ' is missing fields: ' + JSON.stringify(missingFields);
|
||||
}
|
||||
if (unknownFields.length > 0) {
|
||||
errorMessage += (missingFields.length ? ' and' : '')
|
||||
+ ' has unknown fields: ' + JSON.stringify(unknownFields);
|
||||
}
|
||||
|
||||
throw new Error(errorMessage);
|
||||
};
|
||||
|
||||
SerializedObject.prototype.append = function(bytes) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
/* eslint-disable quotes*/
|
||||
|
||||
var assert = require('assert');
|
||||
var lodash = require('lodash');
|
||||
var SerializedObject = require('ripple-lib').SerializedObject;
|
||||
var Amount = require('ripple-lib').Amount;
|
||||
var sjcl = require('ripple-lib').sjcl;
|
||||
@@ -150,6 +151,52 @@ describe('Serialized object', function() {
|
||||
assert.equal("DirectoryNode", output_json.LedgerEntryType);
|
||||
});
|
||||
|
||||
it('checks for missing required fields', function() {
|
||||
var input_json = {
|
||||
TransactionType: 'Payment',
|
||||
// no non required fields
|
||||
Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Amount: '274579388',
|
||||
Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Fee: '15',
|
||||
Sequence: 351,
|
||||
SigningPubKey: '02'
|
||||
};
|
||||
|
||||
Object.keys(input_json).slice(1).forEach(function(k) {
|
||||
var bad_json = lodash.merge({}, input_json);
|
||||
delete bad_json[k];
|
||||
|
||||
assert.strictEqual(bad_json[k], undefined);
|
||||
assert.throws(function() {
|
||||
SerializedObject.from_json(bad_json);
|
||||
}, new RegExp('Payment is missing fields: \\["' + k + '"\\]'));
|
||||
|
||||
});
|
||||
});
|
||||
it('checks for unknown fields', function() {
|
||||
var input_json = {
|
||||
TransactionType: 'Payment',
|
||||
// no non required fields
|
||||
Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Amount: '274579388',
|
||||
Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Fee: '15',
|
||||
Sequence: 351,
|
||||
SigningPubKey: '02'
|
||||
};
|
||||
|
||||
Object.keys(input_json).slice(1).forEach(function(k) {
|
||||
var bad_json = lodash.merge({}, input_json);
|
||||
bad_json[k + 'z'] = bad_json[k];
|
||||
|
||||
assert.throws(function() {
|
||||
SerializedObject.from_json(bad_json);
|
||||
}, new RegExp('Payment has unknown fields: \\["' + k + 'z"\\]'));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Format validation', function() {
|
||||
// Peercover actually had a problem submitting transactions without a `Fee`
|
||||
// and rippled was only informing of "transaction is invalid"
|
||||
|
||||
Reference in New Issue
Block a user