Compare commits

...

17 Commits

Author SHA1 Message Date
Joel Wetzell d3055cb9a5 rework bundle decoding and tests 2026-08-30 09:00:38 -05:00
Joel Wetzell 6012e98efd add more error tests for packet from bytes 2026-08-30 08:44:21 -05:00
Joel Wetzell a30ffb1311 Merge pull request #29 from jwetzell/dependabot/github_actions/actions/setup-go-7
Bump actions/setup-go from 6 to 7
2026-08-06 08:24:39 -05:00
dependabot[bot] f878255c7f Bump actions/setup-go from 6 to 7
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6 to 7.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-20 02:53:37 +00:00
Joel Wetzell 7a5ef4c56b Merge pull request #27 from jwetzell/dependabot/github_actions/actions/checkout-7
Bump actions/checkout from 6 to 7
2026-07-13 13:27:51 -05:00
Joel Wetzell 113cb622e8 Merge pull request #28 from jwetzell/dependabot/go_modules/github.com/urfave/cli/v3-3.10.1
Bump github.com/urfave/cli/v3 from 3.9.0 to 3.10.1
2026-07-13 13:25:51 -05:00
dependabot[bot] 1994949841 Bump github.com/urfave/cli/v3 from 3.9.0 to 3.10.1
Bumps [github.com/urfave/cli/v3](https://github.com/urfave/cli) from 3.9.0 to 3.10.1.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v3.9.0...v3.10.1)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli/v3
  dependency-version: 3.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-29 02:53:22 +00:00
dependabot[bot] fe499f0c21 Bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-22 02:53:16 +00:00
Joel Wetzell 2278ad7a1c Merge pull request #25 from jwetzell/dependabot/github_actions/codecov/codecov-action-7
Bump codecov/codecov-action from 6 to 7
2026-06-10 11:37:11 -05:00
Joel Wetzell d4a56fcd11 rename variables 2026-06-08 12:23:40 -05:00
dependabot[bot] e8626ab230 Bump codecov/codecov-action from 6 to 7
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 6 to 7.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 02:53:29 +00:00
Joel Wetzell 58672c9ab3 mess around with benchmarks and fuzzing 2026-05-20 17:41:57 -05:00
Joel Wetzell 8b8129b2e2 add size check to bundle content 2026-05-20 17:41:37 -05:00
Joel Wetzell f7850ce70e Merge pull request #24 from jwetzell/fix/float-64-arg-size-check
fix size check on readOSCFloat64
2026-05-20 17:39:59 -05:00
Joel Wetzell 82e9c7ed24 Merge pull request #23 from jwetzell/dependabot/go_modules/github.com/urfave/cli/v3-3.9.0
Bump github.com/urfave/cli/v3 from 3.8.0 to 3.9.0
2026-05-19 14:34:06 -05:00
dependabot[bot] 9f34a57141 Bump github.com/urfave/cli/v3 from 3.8.0 to 3.9.0
Bumps [github.com/urfave/cli/v3](https://github.com/urfave/cli) from 3.8.0 to 3.9.0.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v3.8.0...v3.9.0)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli/v3
  dependency-version: 3.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 03:23:16 +00:00
Joel Wetzell 6aadaedb5d some linting things 2026-05-17 09:22:14 -05:00
18 changed files with 162 additions and 64 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
- goarch: "386"
goos: darwin
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
- goarch: "386"
goos: darwin
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
- goarch: "386"
goos: darwin
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
+3 -3
View File
@@ -9,16 +9,16 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Set up Go
uses: actions/setup-go@v6
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Run tests
run: go test -v -coverprofile=coverage.txt .
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v6
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.txt
+26 -37
View File
@@ -45,54 +45,43 @@ func BundleFromBytes(bytes []byte) (*OSCBundle, []byte, error) {
return nil, bytesAfterBundleHeader, errors.New("OSC Bundle must start with #bundle string")
}
timeTag, bytesAfterTimeTag, err := readOSCTimeTag(bytesAfterBundleHeader)
if err != nil {
return nil, bytesAfterBundleHeader, err
}
timeTag, bytesAfterTimeTag, _ := readOSCTimeTag(bytesAfterBundleHeader)
bundleContents := []OSCPacket{}
endOfBundle := false
remainingBytes := bytesAfterTimeTag
for !endOfBundle {
contentSize, bytesAfterContentSize, err := readOSCInt32(remainingBytes)
contentSize, bytesAfterContentSize, _ := readOSCInt32(remainingBytes)
remainingBytes = bytesAfterContentSize
if contentSize <= 0 {
return nil, remainingBytes, errors.New("bundle content size must be positive")
}
if len(remainingBytes) < int(contentSize) {
return nil, remainingBytes, errors.New("bundle doesn't have enough bytes for the content size it specifies")
}
bundleContentBytes := remainingBytes[0:contentSize]
switch bundleContentBytes[0] {
case 35: // #
content, _, err := BundleFromBytes(bundleContentBytes)
if err != nil {
return nil, remainingBytes, err
}
remainingBytes = bytesAfterContentSize
if len(remainingBytes) < int(contentSize) {
return nil, remainingBytes, errors.New("bundle doesn't have enough bytes for the content size it specifies")
bundleContents = append(bundleContents, content)
case 47: // /
content, err := MessageFromBytes(bundleContentBytes)
if err != nil {
return nil, remainingBytes, err
}
bundleContentBytes := remainingBytes[0:contentSize]
if bundleContentBytes[0] == 35 {
content, _, err := BundleFromBytes(bundleContentBytes)
if err != nil {
return nil, remainingBytes, err
}
bundleContents = append(bundleContents, content)
} else if bundleContentBytes[0] == 47 {
content, err := MessageFromBytes(bundleContentBytes)
if err != nil {
return nil, remainingBytes, err
}
bundleContents = append(bundleContents, content)
} else {
return nil, remainingBytes, errors.New("bundle contents does not look a bundle or message")
}
remainingBytes = bytesAfterContentSize[contentSize:]
if len(remainingBytes) == 0 {
endOfBundle = true
}
bundleContents = append(bundleContents, content)
default:
return nil, remainingBytes, errors.New("bundle contents does not look a bundle or message")
}
remainingBytes = bytesAfterContentSize[contentSize:]
return &OSCBundle{
TimeTag: timeTag,
+46
View File
@@ -194,6 +194,24 @@ func TestBadOSCBundleDecoding(t *testing.T) {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
errorString: "bundle contents does not look a bundle or message",
},
{
name: "bundle with bad bundle inside",
bytes: []byte{35, 98, 117, 110, 100, 108, 101, 0, // #bundle
0, 0, 0, 32, 0, 0, 0, 0, // time tag
0, 0, 0, 19, // content size
35, 98, 117, 110, 100, 108, 101, 0, // #bundle
0, 0, 0, 64, 0, 0, 0, 0, // time tag
0, 0, 0},
errorString: "OSC Bundle has to be at least 20 bytes",
},
{
name: "bundle with bad message inside",
bytes: []byte{35, 98, 117, 110, 100, 108, 101, 0, // #bundle
0, 0, 0, 32, 0, 0, 0, 0, // time tag
0, 0, 0, 5, // content size
47, 104, 101, 108, 108, 111},
errorString: "OSC string must be null-terminated",
},
}
for _, testCase := range testCases {
@@ -210,3 +228,31 @@ func TestBadOSCBundleDecoding(t *testing.T) {
})
}
}
func FuzzBundleFromBytes(f *testing.F) {
seedBytes := [][]byte{
{},
{35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0,
32, 0, 0, 0, 0, 0, 0, 0, 32, 47, 111,
115, 99, 105, 108, 108, 97, 116, 111, 114, 47, 52,
47, 102, 114, 101, 113, 117, 101, 110, 99, 121, 0,
44, 102, 0, 0, 67, 220, 0, 0},
{35, 98, 117, 110, 100, 108, 101, 0, // #bundle
0, 0, 0, 32, 0, 0, 0, 0, // time tag
0, 0, 0, 52, // content size
35, 98, 117, 110, 100, 108, 101, 0, // #bundle
0, 0, 0, 64, 0, 0, 0, 0, // time tag
0, 0, 0, 32, // content size
47, 111, 115, 99, 105, 108, 108, 97, 116, 111, 114, 47, 52,
47, 102, 114, 101, 113, 117, 101, 110, 99, 121, 0,
44, 102, 0, 0, 67, 220, 0, 0},
}
for _, seed := range seedBytes {
f.Add(seed)
}
f.Fuzz(func(t *testing.T, data []byte) {
_, _, _ = BundleFromBytes(data)
})
}
+4 -6
View File
@@ -141,11 +141,12 @@ func slipEncode(bytes []byte) []byte {
var encodedBytes = []byte{END}
for _, byteToEncode := range bytes {
if byteToEncode == END {
switch byteToEncode {
case END:
encodedBytes = append(encodedBytes, ESC, ESC_END)
} else if byteToEncode == ESC {
case ESC:
encodedBytes = append(encodedBytes, ESC, ESC_ESC)
} else {
default:
encodedBytes = append(encodedBytes, byteToEncode)
}
}
@@ -178,8 +179,5 @@ func makeMsg(address string, args []string, types []string, slip bool) {
if slip {
oscMessageBuffer = slipEncode(oscMessageBuffer)
}
//TODO write buffer to stdout
os.Stdout.Write(oscMessageBuffer)
}
+7 -6
View File
@@ -120,9 +120,10 @@ func (s *SLIP) decode(bytes []byte) {
}
if escapeNext {
if packetByte == ESC_END {
switch packetByte {
case ESC_END:
s.pendingBytes = append(s.pendingBytes, END)
} else if packetByte == ESC_ESC {
case ESC_ESC:
s.pendingBytes = append(s.pendingBytes, ESC)
}
escapeNext = false
@@ -203,23 +204,23 @@ func handleBundle(bundle *osc.OSCBundle, format string) {
func listenUDP(netAddress string, format string) {
s, err := net.ResolveUDPAddr("udp4", netAddress)
laddr, err := net.ResolveUDPAddr("udp4", netAddress)
if err != nil {
fmt.Println(err)
return
}
connection, err := net.ListenUDP("udp4", s)
conn, err := net.ListenUDP("udp4", laddr)
if err != nil {
fmt.Println(err)
return
}
defer connection.Close()
defer conn.Close()
buffer := make([]byte, 1024)
for {
bytesRead, _, err := connection.ReadFromUDP(buffer)
bytesRead, _, err := conn.ReadFromUDP(buffer)
if err != nil {
panic(err)
+4 -3
View File
@@ -169,11 +169,12 @@ func slipEncode(bytes []byte) []byte {
var encodedBytes = []byte{END}
for _, byteToEncode := range bytes {
if byteToEncode == END {
switch byteToEncode {
case END:
encodedBytes = append(encodedBytes, ESC, ESC_END)
} else if byteToEncode == ESC {
case ESC:
encodedBytes = append(encodedBytes, ESC, ESC_ESC)
} else {
default:
encodedBytes = append(encodedBytes, byteToEncode)
}
}
+1 -1
View File
@@ -2,4 +2,4 @@ module github.com/jwetzell/osc-go
go 1.25.1
require github.com/urfave/cli/v3 v3.8.0
require github.com/urfave/cli/v3 v3.10.1
+2 -2
View File
@@ -4,7 +4,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/urfave/cli/v3 v3.8.0 h1:XqKPrm0q4P0q5JpoclYoCAv0/MIvH/jZ2umzuf8pNTI=
github.com/urfave/cli/v3 v3.8.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/urfave/cli/v3 v3.10.1 h1:7Kx9H50hrHbRbyxgO1KP6/BcbiGRz0uYh5YyQ30JEEY=
github.com/urfave/cli/v3 v3.10.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+43
View File
@@ -511,3 +511,46 @@ func TestBadOSCMessageDecoding(t *testing.T) {
})
}
}
func BenchmarkMessageToBytes(b *testing.B) {
message := &OSCMessage{
Address: "/hello",
Args: []OSCArg{
{Type: "i", Value: 35},
},
}
for b.Loop() {
_, err := message.ToBytes()
if err != nil {
b.Fatalf("failed to encode properly: %s", err.Error())
}
}
}
func BenchmarkMessageFromBytes(b *testing.B) {
bytes := []byte{47, 104, 101, 108, 108, 111, 0, 0, 44, 105, 0, 0, 0, 0, 0, 35}
for b.Loop() {
_, err := MessageFromBytes(bytes)
if err != nil {
b.Fatalf("failed to decode properly: %s", err.Error())
}
}
}
func FuzzMessageFromBytes(f *testing.F) {
seedBytes := [][]byte{
{},
{47, 104, 101, 108, 108, 111, 0, 0},
{47, 104, 101, 108, 108, 111, 0, 0, 44, 105, 0, 0, 0, 0, 0, 35},
}
for _, seed := range seedBytes {
f.Add(seed)
}
f.Fuzz(func(t *testing.T, data []byte) {
_, _ = MessageFromBytes(data)
})
}
+1 -1
View File
@@ -318,7 +318,7 @@ func readOSCArg(bytes []byte, oscType string) (OSCArg, []byte, error) {
oscArg := OSCArg{}
oscArg.Type = oscType
remainingBytes := []byte{}
var remainingBytes []byte
//TODO(jwetzell): add error handling
switch oscType {
case "s":
+14 -2
View File
@@ -292,14 +292,26 @@ func TestBadPacketFromBytes(t *testing.T) {
bytes []byte
errorString string
}{
{name: "empty bytes",
{
name: "empty bytes",
bytes: []byte{},
errorString: "cannot create OSC Packet from empty byte array",
},
{name: "packet that does not start with / or #",
{
name: "packet that does not start with / or #",
bytes: []byte{0, 1, 2, 3},
errorString: "OSC Packet must start with # for bundle or / for message",
},
{
name: "bundle with not enough bytes",
bytes: []byte{35, 98, 117, 110, 100, 108, 101, 0},
errorString: "OSC Bundle has to be at least 20 bytes",
},
{
name: "message without null terminated address",
bytes: []byte{47, 104, 101, 108, 108, 111},
errorString: "OSC string must be null-terminated",
},
}
for _, testCase := range testCases {
+2
View File
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("#bundle\x0000000000\x00\x00\x00\x00")
+2
View File
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("/00\x00,b0\x00\xff000")
+2
View File
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("/00\x00,b0\x00\x00\x00\x00\x010")
+2
View File
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("/00\x00,d\x0000000")