From 203405a76707dba52daad23e62675ac70159beda Mon Sep 17 00:00:00 2001 From: EvgenyOrekhov Date: Fri, 3 Feb 2017 12:14:33 +0300 Subject: [PATCH 1/4] Add a failing test case for #964 Joi wrong value parsing --- test/index.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/index.js b/test/index.js index 40a53377c..1622469f3 100755 --- a/test/index.js +++ b/test/index.js @@ -1760,6 +1760,25 @@ describe('Joi', () => { }).to.throw('invalid value'); done(); }); + + it('throws a validation error and not a TypeError when parameter is given as a json string with incorrect property', (done) => { + + const schema = { + a: Joi.object({ + b: Joi.string() + }) + }; + + const input = { + a: '{"c":"string"}' + }; + + expect(() => { + + Joi.attempt(input, schema); + }).to.throw(/\"c\" is not allowed/); + done(); + }); }); describe('compile()', () => { From 8fb9ea899788ac0d8babd3bac707c8980755a814 Mon Sep 17 00:00:00 2001 From: EvgenyOrekhov Date: Fri, 3 Feb 2017 12:35:57 +0300 Subject: [PATCH 2/4] Fix #964 Joi wrong value parsing --- lib/errors.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/errors.js b/lib/errors.js index 001b31f9e..9397593c4 100755 --- a/lib/errors.js +++ b/lib/errors.js @@ -285,6 +285,9 @@ internals.annotate = function (stripColorCodes) { delete ref[replacement]; } else { + if (typeof ref === 'string') { + ref = JSON.parse(ref); + } ref[`_$miss$_${seg}|${pos}_$end$_`] = '__missing__'; } } From 9d38954b44bfe73fb453abb09247854135b3ff96 Mon Sep 17 00:00:00 2001 From: EvgenyOrekhov Date: Wed, 15 Feb 2017 19:18:00 +0300 Subject: [PATCH 3/4] Add a failing test case for annotate() --- test/errors.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/errors.js b/test/errors.js index 668513893..8e52a2228 100755 --- a/test/errors.js +++ b/test/errors.js @@ -609,5 +609,25 @@ describe('errors', () => { done(); }); }); + + it('pinpoints an error in a stringified JSON object', (done) => { + + const object = { + a: '{"c":"string"}' + }; + + const schema = { + a: Joi.object({ + b: Joi.string() + }) + }; + + Joi.validate(object, schema, { abortEarly: false }, (err, value) => { + + expect(err).to.exist(); + expect(err.annotate(true)).to.equal('{\n \"a\" [1]: \"{\\\"c\\\":\\\"string\\\"}\"\n}\n\n[1] \"c\" is not allowed'); + done(); + }); + }); }); }); From 670233fdca51713eb5816c0840a2f414e2074e5a Mon Sep 17 00:00:00 2001 From: EvgenyOrekhov Date: Thu, 16 Feb 2017 12:00:44 +0300 Subject: [PATCH 4/4] Fix annotate() not pinpointing an error in a stringified JSON object --- lib/errors.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index 9397593c4..4676059bc 100755 --- a/lib/errors.js +++ b/lib/errors.js @@ -252,7 +252,7 @@ internals.annotate = function (stripColorCodes) { let ref = obj; for (let j = 0; j < path.length && ref; ++j) { const seg = path[j]; - if (j + 1 < path.length) { + if (j + 1 < path.length && typeof ref[seg] !== 'string') { ref = ref[seg]; } else { @@ -279,15 +279,14 @@ internals.annotate = function (stripColorCodes) { } else if (lookup[error.path]) { const replacement = lookup[error.path]; - const appended = replacement.replace('_$end$_', `, ${pos}_$end$_`); - ref[appended] = ref[replacement]; - lookup[error.path] = appended; - delete ref[replacement]; + if (typeof ref[replacement] !== 'string') { + const appended = replacement.replace('_$end$_', `, ${pos}_$end$_`); + ref[appended] = ref[replacement]; + lookup[error.path] = appended; + delete ref[replacement]; + } } else { - if (typeof ref === 'string') { - ref = JSON.parse(ref); - } ref[`_$miss$_${seg}|${pos}_$end$_`] = '__missing__'; } }