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

encoding/binary: binary.Read doesn't respect byteOrder when []byte is passed #40891

Closed
nokute78 opened this issue Aug 19, 2020 · 5 comments
Closed

Comments

@nokute78
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.15 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/taka/.cache/go-build"
GOENV="/home/taka/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/taka/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/taka/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/taka/go/src/github.com/nokute78/go-bit/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build405174845=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I tried to read 6 bytes using binary.Read in BigEndian.
https://play.golang.org/p/RUvRdkc0a0W

What did you expect to see?

ret(big)=ffeeddccbbaa
ret(lit)=aabbccddeeff

What did you see instead?

binary.Read returns same value and it seems to ignore byteOrder.

ret(big)=aabbccddeeff
ret(lit)=aabbccddeeff

Background:

The GUID Partition Table (GPT) has mixed endian GUID.
Refer to https://developer.apple.com/library/archive/technotes/tn2166/_index.html#//apple_ref/doc/uid/DTS10003927-CH1-SECTION2

 the GUID for the ESP partition type is shown in the documentation as C12A7328-F81F-11D2-BA4B-00A0C93EC93B, but the bytes written to disk are 0x28 0x73 0x2a 0xc1 0x1f 0xf8 0xd2 0x11 0xba 0x4b 0x00 0xa0 0xc9 0x3e 0xc9 0x3b.

The GUID is encoded like

  • 4bytes (Little Endian)
  • 2bytes (Little Endian)
  • 2bytes (Little Endian)
  • 2bytes (Big Endian)
  • 6bytes (Big Endian)

The point is the last 6bytes 0x00 0xa0 0xc9 0x3e 0xc9 0x3b. It is encoded as Big Endian.
How can we get using binary.Read ?
Does binary.Read support such case?

@davecheney
Copy link
Contributor

davecheney commented Aug 19, 2020

This is because the byte ordering is the byte ordering of the target type which has no meaning when the target is only 8 bits wide.

Said another way, guid is 16 bytes. That’s it, no endianness needed.

@nokute78
Copy link
Author

@davecheney Thank you for comment.

the target is only 8 bits wide.

It is an element size (not an entire slice).
So binary.Read supports only 1,2,4,8,16 bytes which are the size of numeric types, right ?

guid is 16 bytes. That’s it, no endianness needed.

I think we should take care endianness.

MS supports a GUID API to avoid Guid endianness issue. (refer to Remarks)

https://docs.microsoft.com/en-us/archive/blogs/openspecification/guids-and-endianness-endi-an-ne-ssinguid-or-idne-na-en-ssinguid

@davecheney
Copy link
Contributor

So binary.Read supports only 1,2,4,8,16 bytes which are the size of numeric types, right ?

it supports integer types of varying but sizes. If you decode into something larger than a byte then endianness comes into play.

@randall77
Copy link
Contributor

binary.Read does not support what you are trying to do.

binary.Read ignores the endian argument if the data you're reading into is a byte slice. You have to read into a larger type, e.g. int32, for endianness to matter.

You can always reverse your byte slice after reading.

func reverse(b []byte) {
   for i := 0; i < len(b)/2; i++ {
       b[i], b[len(b)-1-i] = b[len(b)-1-i], b[i]
   }
}

@nokute78
Copy link
Author

@davecheney @randall77 Thank you for comment and example code !

I understood binary.Read doesn't support what I want to do.
So, I close this issue.

@golang golang locked and limited conversation to collaborators Aug 20, 2021
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