Skip to content

Critical bugs: Int parameter serialization fails and Response.Payload returns request instead of response #101

@aileen5150

Description

@aileen5150

Critical Bugs Found in gosoap Library

Environment

  • Go version: 1.21+
  • gosoap version: Latest (as of 2024-03-03)
  • OS: Windows/Linux

Bug 1: Int Parameter Serialization Failure

Description

When using int type parameters in gosoap.Params, they are serialized as empty XML tags instead of containing the actual values.

Expected Behavior

<Add xmlns="http://tempuri.org/">
    <a>10</a>
    <b>5</b>
</Add>

Actual Behavior

<Add xmlns="http://tempuri.org/">
    <a></a>
    <b></b>
</Add>

Code to Reproduce

params := gosoap.Params{
    "a": 10,  // int value
    "b": 5,   // int value
}
res, err := soap.Call("Add", params)

Root Cause

In encode.go, the recursiveEncode function only handles reflect.String and reflect.Struct types, but ignores reflect.Int, reflect.Float, etc.

// Current code in encode.go around line 71
switch v.Kind() {
case reflect.String:
    content := xml.CharData(v.String())
    tokens.data = append(tokens.data, content)
case reflect.Struct:
    tokens.data = append(tokens.data, v.Interface())
// Missing: reflect.Int, reflect.Float, reflect.Bool cases
}

Workaround

Use string parameters instead:

params := gosoap.Params{
    "a": "10",  // string value works
    "b": "5",   // string value works
}

Bug 2: Response.Payload Contains Request Instead of Response

Description

The Response.Payload field contains the original request XML instead of the server's response XML.

Expected Behavior

Response.Payload should contain the server's response XML.

Actual Behavior

Response.Payload contains the request XML that was sent to the server.

Code to Reproduce

res, err := soap.Call("Add", params)
fmt.Println(string(res.Payload)) // Shows request XML, not response XML

Root Cause

In soap.go around line 140, the Response struct is incorrectly populated:

// Current buggy code
res = &Response{
    Body:    soap.Body.Contents,
    Header:  soap.Header.Contents,
    Payload: p.Payload,  // BUG: This is the request payload!
}

Should be:

// Fixed code
res = &Response{
    Body:    soap.Body.Contents,
    Header:  soap.Header.Contents,
    Payload: b,  // This is the actual response from server
}

Impact

These bugs make the library unsuitable for production use:

  1. Bug 1 prevents proper parameter passing for numeric types
  2. Bug 2 makes it impossible to debug requests or access raw response data

Suggested Fixes

Fix 1: Add missing type handling in encode.go

// Add after reflect.String case in recursiveEncode function
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    content := xml.CharData(strconv.FormatInt(v.Int(), 10))
    tokens.data = append(tokens.data, content)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    content := xml.CharData(strconv.FormatUint(v.Uint(), 10))
    tokens.data = append(tokens.data, content)
case reflect.Float32, reflect.Float64:
    content := xml.CharData(strconv.FormatFloat(v.Float(), 'f', -1, 64))
    tokens.data = append(tokens.data, content)
case reflect.Bool:
    content := xml.CharData(strconv.FormatBool(v.Bool()))
    tokens.data = append(tokens.data, content)

Fix 2: Correct Response.Payload assignment in soap.go

// Change line ~140 from:
Payload: p.Payload,
// To:
Payload: b,

Additional Notes

  • These bugs have been verified through extensive testing
  • Workarounds exist but shouldn't be necessary
  • The library is otherwise functional for basic SOAP operations

Would appreciate a fix or guidance on contributing a pull request.

Test Server

If needed, I can provide a test SOAP server to reproduce these issues.

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