diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index 0c6029ad360..1ba2564f011 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -1015,6 +1015,17 @@ class AliasType extends @typealias, CompositeType { override Type getUnderlyingType() { result = this.getRhs().getUnderlyingType() } } +/** + * Gets the non-alias type at the end of the alias chain starting at `t`. + * + * If `t` is not an alias type then `result` is `t`. + */ +Type unalias(Type t) { + not t instanceof AliasType and result = t + or + result = unalias(t.(AliasType).getRhs()) +} + /** * A type that implements the builtin interface `error`. */ diff --git a/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql b/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql index 7918b9694ea..6591aa0aa14 100644 --- a/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql +++ b/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql @@ -41,7 +41,7 @@ module UntrustedToPassthroughTypeConversionConfig implements DataFlow::ConfigSig additional predicate isSinkToPassthroughType(DataFlow::TypeCastNode sink, PassthroughTypeName name) { exists(Type typ | typ = sink.getResultType() and - typ.getUnderlyingType*().hasQualifiedName("html/template", name) + unalias(typ).hasQualifiedName("html/template", name) ) } @@ -80,7 +80,7 @@ module PassthroughTypeConversionToTemplateExecutionCallConfig implements DataFlo ) { exists(Type typ | typ = source.getResultType() and - typ.getUnderlyingType*().hasQualifiedName("html/template", name) + unalias(typ).hasQualifiedName("html/template", name) ) }