Skip to content

fix(adt): parseActivationResult and parseSyntaxCheckResults silently ignore SAP error messages due to XML namespace mismatch #136

Description

@txape10

Summary

parseActivationResult reports Success: true even when SAP returns E-type activation errors. parseSyntaxCheckResults may also silently drop error messages. Root cause: Go's encoding/xml does not match namespace-qualified attributes (adtcomp:type="E") against unqualified struct tags (xml:"type,attr").

Root cause

SAP ADT activation responses use namespace-prefixed attributes:

<adtcomp:activationLog xmlns:adtcomp="http://www.sap.com/adt/activation">
  <adtcomp:messages>
    <adtcomp:msg adtcomp:type="E" adtcomp:objDescr="ZTEST" adtcomp:line="5">
      <adtcomp:shortText><adtcomp:txt>Syntax error</adtcomp:txt></adtcomp:shortText>
    </adtcomp:msg>
  </adtcomp:messages>
</adtcomp:activationLog>

Go's xml.Unmarshal matches element names by local name regardless of namespace prefix (so <adtcomp:msg> is found by xml:"msg"), but attribute matching is strict: xml:"type,attr" will NOT match adtcomp:type="E". Result: msg.Type is always "", strings.ContainsAny("", "EAX") is false, and Success stays true.

parseSyntaxCheckResults has a partial workaround (strings.ReplaceAll(xmlStr, "chkrun:", "")) but it turns xmlns:chkrun="..." into a default namespace declaration xmlns="...", which can cause Go's parser to miss elements in that namespace.

Impact

  • Activation errors (syntax errors, ATC findings blocking activation) are silently swallowed — vsp reports success even when SAP refused to activate the object
  • Syntax check results may be missed depending on SAP version / namespace declaration style
  • Affects all object types, but most visible when activating INCL objects where SAP returns error messages without inactiveObjects (the fallback check)

Fix

Add a stripXMLNamespaces() helper that removes all namespace declarations and all prefix: prefixes before unmarshaling. Apply to both parsers.

var (
    reXMLNSDecl   = regexp.MustCompile(`\s*xmlns(?::\w+)?="[^"]*"`)
    reXMLNSPrefix = regexp.MustCompile(`(</?|\s)(\w[\w-]*):([\w])`)
)

func stripXMLNamespaces(data []byte) []byte {
    s := reXMLNSDecl.ReplaceAllString(string(data), "")
    s = reXMLNSPrefix.ReplaceAllString(s, "${1}${3}")
    return []byte(s)
}

We have this fix running on-prem S/4HANA in our fork (txape10/vibing-steampunk, commit dedfebc) with 6 unit tests covering both parsers and both failure modes (with and without inactiveObjects).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions