diff --git a/pkg/workflows/wasm/host/internal/rawsdk/helpers_wasip1.go b/pkg/workflows/wasm/host/internal/rawsdk/helpers_wasip1.go index 3bbfa0a2ac..bfc48c912f 100644 --- a/pkg/workflows/wasm/host/internal/rawsdk/helpers_wasip1.go +++ b/pkg/workflows/wasm/host/internal/rawsdk/helpers_wasip1.go @@ -197,11 +197,12 @@ func await[I, O proto.Message](input I, output O, fn awaitFn) { bytes := fn(mptr, mlen, responsePtr, responseLen) if bytes < 0 { - SendError(errors.New("awaitCapabilities returned an error")) + SendError(fmt.Errorf("awaitCapabilities return an error: %s", response[:-bytes])) } - if proto.Unmarshal(response[:bytes], output) != nil { - SendError(errors.New("failed to proto unmarshal await response")) + err := proto.Unmarshal(response[:bytes], output) + if err != nil { + SendError(fmt.Errorf("failed to unmarshal await response: %w", err)) } } diff --git a/pkg/workflows/wasm/host/module.go b/pkg/workflows/wasm/host/module.go index ade6d044d4..346e353bf7 100644 --- a/pkg/workflows/wasm/host/module.go +++ b/pkg/workflows/wasm/host/module.go @@ -1015,6 +1015,14 @@ func truncateWasmWrite(caller *wasmtime.Caller, src []byte, ptr int32, size int3 return write(memory, src, ptr, size) } +func truncateWasmWriteErr(caller *wasmtime.Caller, src []byte, ptr int32, size int32) int64 { + code := truncateWasmWrite(caller, src, ptr, size) + if code > 0 { + return -int64(len(src)) + } + return code +} + // write copies the given src byte slice into the memory at the given pointer and max size. func write(memory, src []byte, ptr, maxSize int32) int64 { if ptr < 0 { @@ -1145,7 +1153,7 @@ func createAwaitSecretsFn( if err != nil { errStr := fmt.Sprintf("error reading from wasm %s", err) logger.Error(errStr) - return truncateWasmWrite(caller, []byte(errStr), responseBuffer, maxResponseLen) + return truncateWasmWriteErr(caller, []byte(errStr), responseBuffer, maxResponseLen) } req := &sdkpb.AwaitSecretsRequest{} @@ -1153,28 +1161,28 @@ func createAwaitSecretsFn( if err != nil { errStr := err.Error() logger.Error(errStr) - return truncateWasmWrite(caller, []byte(errStr), responseBuffer, maxResponseLen) + return truncateWasmWriteErr(caller, []byte(errStr), responseBuffer, maxResponseLen) } resp, err := exec.awaitSecrets(exec.ctx, req) if err != nil { errStr := err.Error() logger.Error(errStr) - return truncateWasmWrite(caller, []byte(errStr), responseBuffer, maxResponseLen) + return truncateWasmWriteErr(caller, []byte(errStr), responseBuffer, maxResponseLen) } respBytes, err := proto.Marshal(resp) if err != nil { errStr := err.Error() logger.Error(errStr) - return truncateWasmWrite(caller, []byte(errStr), responseBuffer, maxResponseLen) + return truncateWasmWriteErr(caller, []byte(errStr), responseBuffer, maxResponseLen) } size := wasmWrite(caller, respBytes, responseBuffer, maxResponseLen) if size == -1 { errStr := ResponseBufferTooSmall logger.Error(errStr) - return truncateWasmWrite(caller, []byte(errStr), responseBuffer, maxResponseLen) + return truncateWasmWriteErr(caller, []byte(errStr), responseBuffer, maxResponseLen) } return size diff --git a/pkg/workflows/wasm/host/standard_test.go b/pkg/workflows/wasm/host/standard_test.go index 1ae7ac135b..f6cdd4a2d2 100644 --- a/pkg/workflows/wasm/host/standard_test.go +++ b/pkg/workflows/wasm/host/standard_test.go @@ -423,6 +423,20 @@ func TestStandardSecrets(t *testing.T) { require.Equal(t, "Bar", result.GetValue().GetStringValue()) }) + t.Run("returns an error when there are invalid UTF-8 bytes", func(t *testing.T) { + b := []byte{0xff, 0xfe, 0xfd} // invalid UTF-8 bytes + s := string(b) + + result := runSecretTest(t, m, &sdk.SecretResponse{ + Response: &sdk.SecretResponse_Secret{ + Secret: &sdk.Secret{ + Value: s, + }, + }, + }) + require.Equal(t, "Bar", result.GetValue().GetStringValue(), result.GetError()) + }) + t.Run("returns an error if the secret doesn't exist", func(t *testing.T) { resp := runSecretTest(t, m, &sdk.SecretResponse{ Response: &sdk.SecretResponse_Error{