Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/mobile/bind/seq: panic when returning a nil error or "" string from Go to Java through parameter serialization #9271

Closed
rod-hynes opened this issue Dec 11, 2014 · 2 comments

Comments

@rod-hynes
Copy link

  • What version of Go are you using (go version)?
  • What operating system and processor architecture are you using?
    • darwin/amd64 targetting android/arm
  • What did you do?
    • Wrote a Go function that returns type error. Used Java/Go binding and from Java invoked the Go function which returns nil for error value. Under the hood, this is the same as returning a "" string.
  • What did you expect to see?
    • Java wrapper returns after calling the Go function.
  • What did you see instead?
    • The Android process terminates. Presumably due to a panic in Go?

The parameter serialization function Buffer.WriteUTF16("") is called in the case where parameter serialization is returning a nil error. As a test, I changed my code to return a "" string instead of a nil error and that also results in the same process termination.

I suspect the problem is here: https://github.com/golang/mobile/blob/2861ce3b898909384ed7b647e0a167254238c036/bind/seq/utf16.go#L39. In the case where len(s) is 0, the buffer is not grown. But the subsequent line data := b.Data[b.Offset+4:] assumes the buffer is at least 4 bytes and will panic with the default empty buffer.

By modifying WriteUTF16 to skip the string writing entirely in the 0 length case, the serialization works: Java receives the "" or nil error and the process does not terminate.

Incidentally, the b.grow(4 * len(s)) may also be insufficient in a len(s) > 0 case because it only grows the buffer by the maximum possible string length, but the buffer is accessed as if it were 4 + max possible string length bytes due to how the not-yet-allocated initial length prefix is skipped over. In the "everything is surrogate pair" case, could that result in an access past the end of the allocated buffer? To fix this, perhaps the buffer needs to grow by 4 + 4*len(s) just in case.

@rod-hynes
Copy link
Author

After re-reading the gobind doc, perhaps the single return value of type error is not supported? A single return value of type string will still panic when returning "" as reported. I have not determined if an error in the second return value position will panic when nil.

What is the intended way to handle error return values? They seem to be translated into an Exception as shown in the generated code below. But when error is "" an Exception is still thrown?

if err == nil {
    out.WriteUTF16("")
} else {
    out.WriteUTF16(err.Error())
}

And the Java serialization side receives:

String _err = _out.readUTF16();
if (_err != null) {
    throw new Exception(_err);
}

When Go sends "", readUTF16 returns "" to Java, not null, so the Exception is thrown when the error is nil in Go.

@crawshaw
Copy link
Member

Two bugs here. The first is that WriteUTF16 doesn't pre-allocate enough space for the length header, which appears when writing empty strings:

E/Go (21191): panic: runtime error: slice bounds out of range
E/Go (21191): goroutine 18 [running, locked to thread]:
E/Go (21191): golang.org/x/mobile/bind/seq.(*Buffer).WriteUTF16(0x7b3d2080, 0x0, 0x0)
E/Go (21191): /Users/crawshaw/src/golang.org/x/mobile/bind/seq/utf16.go:41 +0x78

The second is that Java_go_seq_readUTF16 allocates an empty Java string for an empty Go string, instead of returning NULL, which trips up the the error->exception logic. I have a test that exercises both.

Unfortunately, you couldn't see that panic in your adb logcat output because I didn't get the CL to redirect panic output in until after the Go 1.4 release. If you use tip, you'll see the message.

Thanks the bug report.

rod-hynes added a commit to rod-hynes/psiphon-tunnel-core that referenced this issue Dec 12, 2014
@mikioh mikioh changed the title mobile/bind/seq: panic when returning a nil error or "" string from Go to Java through parameter serialization x/mobile/bind/seq: panic when returning a nil error or "" string from Go to Java through parameter serialization Aug 5, 2015
@golang golang locked and limited conversation to collaborators Aug 5, 2016
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
Fixes golang/go#9271.

Change-Id: I57dcd11ae5afdc23bc9b1a0945d0789c9feeefb1
Reviewed-on: https://go-review.googlesource.com/1423
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants