Skip to content

Commit

Permalink
Merge pull request #3043 from egorFiNE/fix_js_datetime_functions
Browse files Browse the repository at this point in the history
Exchange: datetime functions sanitized input
  • Loading branch information
kroitor committed Jun 5, 2018
2 parents c407cd6 + 994179a commit c9c7019
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 8 deletions.
69 changes: 61 additions & 8 deletions js/base/Exchange.js
Expand Up @@ -182,15 +182,68 @@ module.exports = class Exchange {
this.proxy = ''
this.origin = '*' // CORS origin

this.iso8601 = timestamp => ((typeof timestamp === 'undefined') ? timestamp : new Date (timestamp).toISOString ())
this.parse8601 = x => Date.parse ((((x.indexOf ('+') >= 0) || (x.slice (-1) === 'Z')) ? x : (x + 'Z').replace (/\s(\d\d):/, 'T$1:')))
this.parseDate = (x) => {
if (typeof x === 'undefined')
return x
return ((x.indexOf ('GMT') >= 0) ?
Date.parse (x) :
this.parse8601 (x))
this.iso8601 = (timestamp) => {
const _timestampNumber = parseInt (timestamp, 10);

// undefined, null and lots of nasty non-numeric values yield NaN
if (isNaN (_timestampNumber) || _timestampNumber < 0) {
return undefined;
}

if (_timestampNumber < 0) {
return undefined;
}

// last line of defence
try {
return new Date (_timestampNumber).toISOString ();
} catch (e) {
return undefined;
}
}

this.parse8601 = (x) => {
if (typeof x !== 'string' || !x) {
return undefined;
}

if (x.match (/^[0-9]+$/)) {
// a valid number in a string, not a date.
return undefined;
}

if (x.indexOf ('-') < 0 || x.indexOf (':') < 0) { // no date can be without a dash and a colon
return undefined;
}

// last line of defence
try {
const candidate = Date.parse (((x.indexOf ('+') >= 0) || (x.slice (-1) === 'Z')) ? x : (x + 'Z').replace (/\s(\d\d):/, 'T$1:'));
if (isNaN (candidate)) {
return undefined;
}
return candidate;
} catch (e) {
return undefined;
}
}

this.parseDate = (x) => {
if (typeof x !== 'string' || !x) {
return undefined;
}

if (x.indexOf ('GMT') >= 0) {
try {
return Date.parse (x);
} catch (e) {
return undefined;
}
}

return this.parse8601 (x);
}

this.microseconds = () => now () * 1000 // TODO: utilize performance.now for that purpose
this.seconds = () => Math.floor (now () / 1000)

Expand Down
72 changes: 72 additions & 0 deletions js/test/base/functions/test.datetime.js
@@ -0,0 +1,72 @@
'use strict'

/* ------------------------------------------------------------------------ */

const { setTimeout_safe
, timeout
, now
, isWindows,
Exchange } = require ('../../../../ccxt')

// const { Exchange, keys, values, unique, index, aggregate } = require ('../../../ccxt')

const { strictEqual: equal } = require ('assert')

/* ------------------------------------------------------------------------ */

it ('iso8601', done => {
const exchange = new Exchange ({
'id': 'chernobyl'
});

equal (exchange.iso8601(514862627000), '1986-04-26T01:23:47.000Z');
equal (exchange.iso8601(0), '1970-01-01T00:00:00.000Z');

equal (exchange.iso8601(-1), undefined);
equal (exchange.iso8601(), undefined);
equal (exchange.iso8601(null), undefined);
equal (exchange.iso8601(''), undefined);
equal (exchange.iso8601('a'), undefined);
equal (exchange.iso8601({}), undefined);

done();
});

/* ------------------------------------------------------------------------ */

it ('parse8601', done => {
const exchange = new Exchange ({
'id': 'fukusima'
});

equal(exchange.parse8601('1986-04-26T01:23:47.000Z'), 514862627000);

equal(exchange.parse8601('1977-13-13T00:00:00.000Z'), undefined);
equal(exchange.parse8601('1986-04-26T25:71:47.000Z'), undefined);

equal(exchange.parse8601('3333'), undefined);
equal(exchange.parse8601('Sr90'), undefined);
equal(exchange.parse8601(''), undefined);
equal(exchange.parse8601(), undefined);
equal(exchange.parse8601(null), undefined);
equal(exchange.parse8601({}), undefined);
equal(exchange.parse8601(33), undefined);

done();
});

/* ------------------------------------------------------------------------ */

it ('parseDate', done => {
const exchange = new Exchange ({
'id': 'TMI'
});

equal(exchange.parseDate('1986-04-26 00:00:00'), 514857600000);
equal(exchange.parseDate('1986-04-26T01:23:47.000Z'), 514862627000);
equal(exchange.parseDate('1986-13-13 00:00:00'), undefined);

done();
});

/* ------------------------------------------------------------------------ */
1 change: 1 addition & 0 deletions js/test/base/test.base.js
Expand Up @@ -19,6 +19,7 @@ describe ('ccxt base code', () => {
require ('./functions/test.number')
require ('./functions/test.time')
require ('./functions/test.type')
require ('./functions/test.datetime')

/* ------------------------------------------------------------------------ */

Expand Down

0 comments on commit c9c7019

Please sign in to comment.