不要怂,就是干,撸起袖子干!

Commit 3f11bd97 by Mick Hansen

refactor(sql): change .field$ to {: model.field} for security reasons, closes #4680

1 parent 87358fae
...@@ -133,7 +133,7 @@ $contains: [1, 2] // @> [1, 2] (PG array contains operator) ...@@ -133,7 +133,7 @@ $contains: [1, 2] // @> [1, 2] (PG array contains operator)
$contained: [1, 2] // <@ [1, 2] (PG array contained by operator) $contained: [1, 2] // <@ [1, 2] (PG array contained by operator)
$any: [2,3] // ANY ARRAY[2, 3]::INTEGER (PG only) $any: [2,3] // ANY ARRAY[2, 3]::INTEGER (PG only)
$eq: '$user.organization_id$' // = "user"."organization_id", with dialect specific column identifiers, PG in this example $col: '$user.organization_id$' // = "user"."organization_id", with dialect specific column identifiers, PG in this example
``` ```
### Combinations ### Combinations
......
...@@ -2161,18 +2161,29 @@ var QueryGenerator = { ...@@ -2161,18 +2161,29 @@ var QueryGenerator = {
}).join(' AND '); }).join(' AND ');
} else if (value && value.$raw) { } else if (value && value.$raw) {
value = value.$raw; value = value.$raw;
} else if (value && value.$col) {
value = value.$col.split('.').map(this.quoteIdentifier.bind(this)).join('.');
} else { } else {
var escapeValue = true;
if (_.isPlainObject(value)) { if (_.isPlainObject(value)) {
_.forOwn(value, function (item, key) { _.forOwn(value, function (item, key) {
if (comparatorMap[key]) { if (comparatorMap[key]) {
comparator = comparatorMap[key]; comparator = comparatorMap[key];
value = item; value = item;
if (_.isPlainObject(value) && value.$any){
if (_.isPlainObject(value) && value.$any) {
comparator += ' ANY'; comparator += ' ANY';
value = value.$any; value = value.$any;
} else if (_.isPlainObject(value) && value.$all) {
comparator += ' ALL';
value = value.$all;
} else if (value && value.$col) {
escapeValue = false;
value = this.whereItemQuery(null, value);
} }
} }
}); }, this);
} }
if (comparator === '=' && value === null) { if (comparator === '=' && value === null) {
...@@ -2181,9 +2192,7 @@ var QueryGenerator = { ...@@ -2181,9 +2192,7 @@ var QueryGenerator = {
comparator = 'IS NOT'; comparator = 'IS NOT';
} }
if (Utils.isColString(value)) { if (escapeValue) {
value = value.substr(1, value.length - 2).split('.').map(this.quoteIdentifier.bind(this)).join('.');
} else {
value = this.escape(value, field); value = this.escape(value, field);
} }
} }
......
...@@ -270,7 +270,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -270,7 +270,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
include: [ include: [
{association: User.Tasks, on: { {association: User.Tasks, on: {
$or: [ $or: [
{'$User.id_user$': '$Tasks.user_id$'}, {'$User.id_user$': {$col: 'Tasks.user_id'}},
{'$Tasks.user_id$': 2} {'$Tasks.user_id$': 2}
] ]
}} }}
...@@ -286,7 +286,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -286,7 +286,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
include: Sequelize.Model.$validateIncludedElements({ include: Sequelize.Model.$validateIncludedElements({
model: User, model: User,
include: [ include: [
{association: User.Tasks, on: {'user_id': '$User.alternative_id$'}} {association: User.Tasks, on: {'user_id': {$col: 'User.alternative_id'}}}
] ]
}).include[0] }).include[0]
}, { }, {
......
...@@ -307,18 +307,38 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -307,18 +307,38 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
}); });
suite('$col', function () { suite('$col', function () {
testsql('userId', '$user.id$', { testsql('userId', {
$col: 'user.id'
}, {
default: '[userId] = [user].[id]'
});
testsql('userId', {
$eq: {
$col: 'user.id'
}
}, {
default: '[userId] = [user].[id]' default: '[userId] = [user].[id]'
}); });
testsql('userId', {
$gt: {
$col: 'user.id'
}
}, {
default: '[userId] > [user].[id]'
});
testsql('$or', [ testsql('$or', [
{'ownerId': '$user.id$'}, {'ownerId': {$col: 'user.id'}},
{'ownerId': '$organization.id$'} {'ownerId': {$col: 'organization.id'}}
], { ], {
default: '([ownerId] = [user].[id] OR [ownerId] = [organization].[id])' default: '([ownerId] = [user].[id] OR [ownerId] = [organization].[id])'
}); });
testsql('$organization.id$', '$user.organizationId$', { testsql('$organization.id$', {
$col: 'user.organizationId'
}, {
default: '[organization].[id] = [user].[organizationId]' default: '[organization].[id] = [user].[organizationId]'
}); });
}); });
...@@ -331,7 +351,9 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -331,7 +351,9 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
}); });
testsql('created_at', { testsql('created_at', {
$lt: '$updated_at$' $lt: {
$col: 'updated_at'
}
}, { }, {
default: '[created_at] < [updated_at]' default: '[created_at] < [updated_at]'
}); });
...@@ -510,6 +532,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -510,6 +532,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
}, { }, {
postgres: "\"userId\" LIKE ANY ARRAY['foo','bar','baz']" postgres: "\"userId\" LIKE ANY ARRAY['foo','bar','baz']"
}); });
testsql('userId', { testsql('userId', {
$iLike: { $iLike: {
$any: ['foo', 'bar', 'baz'] $any: ['foo', 'bar', 'baz']
...@@ -517,6 +540,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -517,6 +540,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
}, { }, {
postgres: "\"userId\" ILIKE ANY ARRAY['foo','bar','baz']" postgres: "\"userId\" ILIKE ANY ARRAY['foo','bar','baz']"
}); });
testsql('userId', { testsql('userId', {
$notLike: { $notLike: {
$any: ['foo', 'bar', 'baz'] $any: ['foo', 'bar', 'baz']
...@@ -524,6 +548,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -524,6 +548,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
}, { }, {
postgres: "\"userId\" NOT LIKE ANY ARRAY['foo','bar','baz']" postgres: "\"userId\" NOT LIKE ANY ARRAY['foo','bar','baz']"
}); });
testsql('userId', { testsql('userId', {
$notILike: { $notILike: {
$any: ['foo', 'bar', 'baz'] $any: ['foo', 'bar', 'baz']
...@@ -531,6 +556,14 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -531,6 +556,14 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
}, { }, {
postgres: "\"userId\" NOT ILIKE ANY ARRAY['foo','bar','baz']" postgres: "\"userId\" NOT ILIKE ANY ARRAY['foo','bar','baz']"
}); });
testsql('userId', {
$notILike: {
$all: ['foo', 'bar', 'baz']
}
}, {
postgres: "\"userId\" NOT ILIKE ALL ARRAY['foo','bar','baz']"
});
}); });
}); });
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!