@@ -94,6 +94,11 @@ module Vue {
9494 )
9595 }
9696
97+ /**
98+ * Gets the template element used by this instance, if any.
99+ */
100+ abstract Template:: Element getTemplateElement ( ) ;
101+
97102 /**
98103 * Gets the node for the `data` option object of this instance.
99104 */
@@ -245,6 +250,8 @@ module Vue {
245250 }
246251
247252 override DataFlow:: Node getOwnOption ( string name ) { result = def .getOptionArgument ( 0 , name ) }
253+
254+ override Template:: Element getTemplateElement ( ) { none ( ) }
248255 }
249256
250257 /**
@@ -264,6 +271,8 @@ module Vue {
264271 }
265272
266273 override DataFlow:: Node getOwnOption ( string name ) { result = extend .getOptionArgument ( 0 , name ) }
274+
275+ override Template:: Element getTemplateElement ( ) { none ( ) }
267276 }
268277
269278 /**
@@ -291,6 +300,8 @@ module Vue {
291300 or
292301 result = MkExtendedVue ( extend ) .( ExtendedVue ) .getOption ( name )
293302 }
303+
304+ override Template:: Element getTemplateElement ( ) { none ( ) }
294305 }
295306
296307 /**
@@ -310,6 +321,8 @@ module Vue {
310321 }
311322
312323 override DataFlow:: Node getOwnOption ( string name ) { result = def .getOptionArgument ( 1 , name ) }
324+
325+ override Template:: Element getTemplateElement ( ) { none ( ) }
313326 }
314327
315328 /**
@@ -320,6 +333,14 @@ module Vue {
320333
321334 SingleFileComponent ( ) { this = MkSingleFileComponent ( file ) }
322335
336+ override Template:: Element getTemplateElement ( ) {
337+ exists ( HTML:: Element e | result .( Template:: HtmlElement ) .getElement ( ) = e |
338+ e .getFile ( ) = file and
339+ e .getName ( ) = "template" and
340+ e .isTopLevel ( )
341+ )
342+ }
343+
323344 override predicate hasLocationInfo (
324345 string filepath , int startline , int startcolumn , int endline , int endcolumn
325346 ) {
@@ -366,4 +387,85 @@ module Vue {
366387 class VueFile extends File {
367388 VueFile ( ) { getExtension ( ) = "vue" }
368389 }
390+
391+ /**
392+ * A taint propagating data flow edge through a Vue instance property.
393+ */
394+ class InstanceHeapStep extends TaintTracking:: AdditionalTaintStep {
395+ DataFlow:: Node src ;
396+
397+ InstanceHeapStep ( ) {
398+ exists ( Instance i , string name , DataFlow:: FunctionNode bound |
399+ bound .flowsTo ( i .getABoundFunction ( ) ) and
400+ not bound .getFunction ( ) instanceof ArrowFunctionExpr and
401+ bound .getReceiver ( ) .getAPropertyRead ( name ) = this and
402+ src = i .getAPropertyValue ( name )
403+ )
404+ }
405+
406+ override predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) { pred = src and succ = this }
407+ }
408+
409+ /*
410+ * Provides classes for working with Vue templates.
411+ */
412+
413+ module Template {
414+ // Currently only supports HTML elements, but it may be possible to parse simple string templates later
415+ private newtype TElement = MkHtmlElement ( HTML:: Element e ) { e .getFile ( ) instanceof VueFile }
416+
417+ /**
418+ * An element of a template.
419+ */
420+ abstract class Element extends TElement {
421+ /** Gets a textual representation of this element. */
422+ string toString ( ) { result = "<" + getName ( ) + ">...</>" }
423+
424+ /**
425+ * Holds if this element is at the specified location.
426+ * The location spans column `startcolumn` of line `startline` to
427+ * column `endcolumn` of line `endline` in file `filepath`.
428+ * For more information, see
429+ * [locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
430+ */
431+ predicate hasLocationInfo (
432+ string filepath , int startline , int startcolumn , int endline , int endcolumn
433+ ) {
434+ filepath = "" and
435+ startline = 0 and
436+ startcolumn = 0 and
437+ endline = 0 and
438+ endcolumn = 0
439+ }
440+
441+ /**
442+ * Gets the name of this element.
443+ *
444+ * For example, the name of `<br>` is `br`.
445+ */
446+ abstract string getName ( ) ;
447+ }
448+
449+ /**
450+ * An HTML element as a template element.
451+ */
452+ class HtmlElement extends Element , MkHtmlElement {
453+ HTML:: Element elem ;
454+
455+ HtmlElement ( ) { this = MkHtmlElement ( elem ) }
456+
457+ override predicate hasLocationInfo (
458+ string filepath , int startline , int startcolumn , int endline , int endcolumn
459+ ) {
460+ elem .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
461+ }
462+
463+ override string getName ( ) { result = elem .getName ( ) }
464+
465+ /**
466+ * Gets the HTML element of this element.
467+ */
468+ HTML:: Element getElement ( ) { result = elem }
469+ }
470+ }
369471}
0 commit comments