Skip to content

Commit b4126d2

Browse files
authored
[latest] escape JSONArray and JSONObject (#126)
* escape JSONArray and JSONObject * 2.14.8
1 parent 6b77f34 commit b4126d2

File tree

3 files changed

+60
-30
lines changed

3 files changed

+60
-30
lines changed

package-lock.json

Lines changed: 13 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@themost/query",
3-
"version": "2.14.7",
3+
"version": "2.14.8",
44
"description": "MOST Web Framework Codename ZeroGravity - Query Module",
55
"main": "dist/index.cjs.js",
66
"module": "dist/index.esm.js",
@@ -24,6 +24,7 @@
2424
"homepage": "https://github.com/themost-framework/query#readme",
2525
"dependencies": {
2626
"@themost/events": "^1.0.5",
27+
"@themost/json": "^1.1.0",
2728
"async": "^3.2.3",
2829
"esprima": "^4.0.0",
2930
"lodash": "^4.17.21",

src/formatter.js

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { instanceOf } from './instance-of';
77
import './polyfills';
88
import { ObjectNameValidator } from './object-name.validator';
99
import { isNameReference, trimNameReference } from './name-reference';
10+
import { JSONArray, JSONObject } from '@themost/json';
1011

1112
class AbstractMethodError extends Error {
1213
constructor() {
@@ -133,6 +134,9 @@ class SqlFormatter {
133134
return SqlUtils.escape(null);
134135

135136
if (typeof value === 'object') {
137+
if (value instanceof JSONArray || value instanceof JSONObject) {
138+
return SqlUtils.escape(value.toString());
139+
}
136140
//add an exception for Date object
137141
if (value instanceof Date)
138142
return SqlUtils.escape(value);
@@ -747,17 +751,28 @@ class SqlFormatter {
747751
const queryEntity = item;
748752
sqlSelect = this.escapeEntity(queryEntity.name);
749753
// get alias
750-
sqlAlias = queryEntity.$alias;
754+
sqlAlias = queryEntity.$alias ? this.escapeName(queryEntity.$alias) : null;
751755
} else if (typeof item === 'string') {
752756
sqlSelect = this.escapeEntity(item)
753757
} else {
754-
/**
755-
* @type {QueryExpression}
756-
*/
757-
const queryExpression = item;
758-
// get alias
759-
sqlAlias = queryExpression.$alias;
760-
sqlSelect = '(' + this.format(queryExpression) + ')';
758+
// try to validate if item is a query expression with a single field
759+
// e.g. { paymentMethods: { $jsonEach: 'paymentMethods' } }
760+
// which is equivalent to SELECT json_each(paymentMethods) AS paymentMethods
761+
const [key] = Object.keys(item);
762+
if (Object.prototype.hasOwnProperty.call(item[key], '$jsonEach')) {
763+
sqlSelect = $this.escape(item);
764+
sqlAlias = this.escapeName(key);
765+
} else if (Object.prototype.hasOwnProperty.call(item, '$select')) {
766+
/**
767+
* @type {QueryExpression}
768+
*/
769+
const queryExpression = item;
770+
// get alias
771+
sqlAlias = queryExpression.$alias ? this.escapeName(queryExpression.$alias) : null;
772+
sqlSelect = '(' + this.format(queryExpression) + ')';
773+
} else {
774+
throw new Error('Invalid additional select expression.');
775+
}
761776
}
762777
if (sqlAlias) {
763778
if (aliasKeyword) {
@@ -1009,15 +1024,15 @@ class SqlFormatter {
10091024
* @type {SqlFormatter}
10101025
*/
10111026
const formatter = new FormatterCtor();
1012-
for (var key in select) {
1027+
for (let key in select) {
10131028
if (Object.prototype.hasOwnProperty.call(select, key)) {
1014-
var selectFields = select[key];
1029+
const selectFields = select[key];
10151030
fields = selectFields.map(function(selectField) {
10161031
let name;
10171032
if (selectField instanceof QueryField) {
10181033
name = selectField.as() || selectField.getName();
10191034
} else {
1020-
var field = new QueryField(selectField);
1035+
const field = new QueryField(selectField);
10211036
name = field.as() || field.getName();
10221037
}
10231038
if (name == null) {
@@ -1191,7 +1206,7 @@ class SqlFormatter {
11911206
if (isNil(obj))
11921207
return null;
11931208
//if a format is defined
1194-
if (s !== undefined) {
1209+
if (typeof s === 'string') {
11951210
if ((s === '%f') || (s === '%ff')) {
11961211
//field formatting
11971212
let field = new QueryField();
@@ -1201,11 +1216,12 @@ class SqlFormatter {
12011216
else
12021217
field = Object.assign(new QueryField(), obj);
12031218
return this.formatFieldEx(field, s);
1204-
}
1205-
else if (s === '%o') {
1219+
} else if (s === '%o') {
12061220
if (instanceOf(obj, QueryExpression))
12071221
return this.formatOrder(obj.$order);
12081222
return this.formatOrder(obj);
1223+
} else {
1224+
throw new Error('Invalid format expression.');
12091225
}
12101226
}
12111227

@@ -1220,27 +1236,32 @@ class SqlFormatter {
12201236
query = Object.assign(new QueryExpression(), obj);
12211237
}
12221238
//format query
1223-
if (isObject(query.$select)) {
1239+
const filtered = typeof query.$where === 'object' || typeof query.$prepared === 'object';
1240+
if (typeof query.$select === 'object') {
12241241
if (isString(query.$count)) {
12251242
return this.formatCount(query);
12261243
}
12271244
if (!query.hasPaging())
12281245
return this.formatSelect(query);
1229-
12301246
else
12311247
return this.formatLimitSelect(query);
1232-
}
1233-
else if (isObject(query.$insert))
1248+
} else if (typeof query.$insert === 'object') {
12341249
return this.formatInsert(query);
1235-
else if (isObject(query.$update))
1250+
} else if (typeof query.$update === 'object') {
1251+
if (filtered === false) {
1252+
throw new Error('Invalid update expression. Expected a valid where clause.');
1253+
}
12361254
return this.formatUpdate(query);
1237-
else if (query.$delete !== null)
1255+
} else if (typeof query.$delete === 'object' || typeof query.$delete === 'string') {
1256+
if (filtered === false) {
1257+
throw new Error('Invalid delete expression. Expected a valid where clause.');
1258+
}
12381259
return this.formatDelete(query);
1239-
else if (query.$where !== null)
1260+
} else if (typeof query.$where === 'object') {
12401261
return this.formatWhere(query.$where);
1241-
1242-
else
1243-
return null;
1262+
} else {
1263+
throw new Error('Invalid source expression. Expected a valid query expression.');
1264+
}
12441265

12451266
}
12461267
$eq(left, right) {

0 commit comments

Comments
 (0)