Skip to content

Commit e25df0a

Browse files
Merge pull request #60 from Trivadis/bugfix/issue-56-assignment-in-declare
Bugfix false positive in G-9501 when using assignment in variable/constant of declare section
2 parents 6fe9e26 + 48a0121 commit e25df0a

File tree

2 files changed

+125
-1
lines changed

2 files changed

+125
-1
lines changed

src/main/java/com/trivadis/tvdcc/validators/SQLInjection.xtend

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import org.eclipse.xtext.nodemodel.util.NodeModelUtils
4747
import org.eclipse.xtext.validation.Check
4848
import org.eclipse.xtext.validation.EValidatorRegistrar
4949
import com.trivadis.oracle.plsql.plsql.ConstantDeclaration
50+
import java.util.ArrayList
5051

5152
class SQLInjection extends PLSQLValidator implements PLSQLCopValidator {
5253
HashMap<Integer, PLSQLCopGuideline> guidelines
@@ -215,6 +216,56 @@ class SQLInjection extends PLSQLValidator implements PLSQLCopValidator {
215216
return ""
216217
}
217218
219+
def contains(EObject obj, String name) {
220+
val names = EcoreUtil2.getAllContentsOfType(obj, SimpleExpressionNameValue)
221+
for (n : names) {
222+
if (n.value.equalsIgnoreCase(name)) {
223+
return true
224+
}
225+
}
226+
return false
227+
}
228+
229+
def getItemsWithDefaults(SimpleExpressionNameValue n) {
230+
var Body body = n.body
231+
var DeclareSection decl
232+
if (body === null) {
233+
decl = EcoreUtil2.getContainerOfType(n, DeclareSection)
234+
} else {
235+
decl = body.declareSection
236+
}
237+
val items = new ArrayList<SimpleExpressionNameValue>
238+
val variables = EcoreUtil2.getAllContentsOfType(decl, VariableDeclaration)
239+
for (v : variables) {
240+
if (v.getDefault() !== null) {
241+
if (v.getDefault().contains(n.value)) {
242+
items.add(v.variable)
243+
}
244+
}
245+
}
246+
val constants = EcoreUtil2.getAllContentsOfType(decl, ConstantDeclaration)
247+
for (c: constants) {
248+
if (c.getDefault() !== null) {
249+
if (c.getDefault().contains(n.value)) {
250+
items.add(c.constant)
251+
}
252+
}
253+
}
254+
if (body !== null) {
255+
val bodyItems = new ArrayList<SimpleExpressionNameValue>
256+
val names = EcoreUtil2.getAllContentsOfType(body, SimpleExpressionNameValue)
257+
for (name : names) {
258+
for (item : items) {
259+
if (name.value.equalsIgnoreCase(item.value)) {
260+
bodyItems.add(name)
261+
}
262+
263+
}
264+
}
265+
items.addAll(bodyItems)
266+
}
267+
return items;
268+
}
218269
219270
def isAsserted(SimpleExpressionNameValue n) {
220271
var EObject obj = EcoreUtil2.getContainerOfType(n, Body)
@@ -232,6 +283,20 @@ class SQLInjection extends PLSQLValidator implements PLSQLCopValidator {
232283
}
233284
return false
234285
}
286+
287+
def isAssertedInParameterOrConstantsOrVariables(SimpleExpressionNameValue n) {
288+
// check parameter fist
289+
if (n.isAsserted) {
290+
return true
291+
}
292+
// check constants and variables with an assignment of the parameter
293+
for (item : getItemsWithDefaults(n)) {
294+
if (isAsserted(item)) {
295+
return true
296+
}
297+
}
298+
return false
299+
}
235300
236301
def isParameterName(SimpleExpressionNameValue n) {
237302
if (n.eContainer instanceof FunctionOrParenthesisParameter) {
@@ -252,7 +317,7 @@ class SQLInjection extends PLSQLValidator implements PLSQLCopValidator {
252317
def void check(SimpleExpressionNameValue n, HashMap<String, SimpleExpressionNameValue> expressions) {
253318
if (!n.parameterName) {
254319
if (n.isParameter) {
255-
if (!n.isAsserted) {
320+
if (!n.isAssertedInParameterOrConstantsOrVariables) {
256321
warning(9501, n, n)
257322
return
258323
}
@@ -294,6 +359,33 @@ class SQLInjection extends PLSQLValidator implements PLSQLCopValidator {
294359
}
295360
return declareSection;
296361
}
362+
363+
def Body getBody(EObject obj) {
364+
val parent = obj.eContainer
365+
var Body body
366+
if (parent instanceof CreateFunction) {
367+
body = parent.body
368+
} else if (parent instanceof CreateProcedure) {
369+
body = parent.body
370+
} else if (parent instanceof FuncDeclInType) {
371+
body = parent.body
372+
} else if (parent instanceof ProcDeclInType) {
373+
body = parent.body
374+
} else if (parent instanceof ConstructorDeclaration) {
375+
body = parent.body
376+
} else if (parent instanceof PlsqlBlock) {
377+
body = parent.body
378+
} else if (parent instanceof FunctionDefinition) {
379+
body = parent.body
380+
} else if (parent instanceof ProcedureDefinition) {
381+
body = parent.body
382+
} else if (parent === null) {
383+
body = null;
384+
} else {
385+
body = getBody(parent);
386+
}
387+
return body;
388+
}
297389
298390
def HashMap<String, SimpleExpressionNameValue> getSimpleExpressinNamesFromAssignments(SimpleExpressionNameValue n) {
299391
val expressions = new HashMap<String, SimpleExpressionNameValue>

src/test/java/com/trivadis/tvdcc/validators/tests/SQLInjectionTest.xtend

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,4 +514,36 @@ class SQLInjectionTest extends AbstractValidatorTest {
514514
Assert.assertEquals(0, issues.size)
515515
}
516516

517+
@Test
518+
def void issue56_using_asserted_variable_with_default_in_execute_immediate() {
519+
val stmt = '''
520+
create or replace procedure exec_sql(in_sql in varchar2) is
521+
l_sql varchar2(1000 char) := in_sql;
522+
l_sql_asserted varchar2(1000 char);
523+
begin
524+
l_sql_asserted := sys.dbms_assert.noop(l_sql);
525+
execute immediate l_sql_asserted;
526+
end exec_sql;
527+
/
528+
'''
529+
val issues = stmt.issues
530+
Assert.assertEquals(0, issues.size)
531+
}
532+
533+
@Test
534+
def void issue56_using_asserted_constant_with_default_in_execute_immediate() {
535+
val stmt = '''
536+
create or replace procedure exec_sql(in_sql in varchar2) is
537+
co_sql constant varchar2(1000 char) := in_sql;
538+
l_sql_asserted varchar2(1000 char);
539+
begin
540+
l_sql_asserted := sys.dbms_assert.noop(co_sql);
541+
execute immediate l_sql_asserted;
542+
end exec_sql;
543+
/
544+
'''
545+
val issues = stmt.issues
546+
Assert.assertEquals(0, issues.size)
547+
}
548+
517549
}

0 commit comments

Comments
 (0)