Files
yggdrasil-go/contrib/mobile/mobile_test.go
Alex Melan dd056e006c fix: avoid panics on edge-case input across modules (#1343)
## Summary
- ipv6rwc: validate IPv6 packet length before reading the version nibble
in writePC
- config: guard the BOM check against configs shorter than two bytes
- admin: replace unchecked net.Error type assertion with errors.As;
tolerate empty unix socket paths
- multicast: log and continue on ReadFrom errors instead of panicking;
use checked type assertion on UDPAddr
- mobile: reject negative length in SendBuffer; nil-check AddrForKey in
GetPeersJSON and SummaryForConfig
- admin/get{tree,paths,sessions}: skip entries when AddrForKey returns
nil instead of dereferencing
- core/nodeinfo: validate the requested public key length in
nodeInfoAdminHandler, matching the other proto handlers
- add regression tests for the panic paths

## Why
A handful of error paths and platform-API edge cases reach fixed-size
indexing or unchecked type assertions before any length validation.
Most are reachable only locally (an empty config piped to -useconf,
a 0-byte packet from the mobile bindings, an admin DialTimeout error
that doesn't satisfy net.Error on some platforms), but they crash the
daemon hard. Have them return errors or skip the entry instead.

## Testing
- go test ./...
- go vet ./...
2026-05-12 21:42:57 +01:00

55 lines
1.5 KiB
Go

package mobile
import (
"os"
"testing"
"github.com/gologme/log"
)
func TestStartYggdrasil(t *testing.T) {
logger := log.New(os.Stdout, "", 0)
logger.EnableLevel("error")
logger.EnableLevel("warn")
logger.EnableLevel("info")
ygg := &Yggdrasil{
logger: logger,
}
if err := ygg.StartAutoconfigure(); err != nil {
t.Fatalf("Failed to start Yggdrasil: %s", err)
}
t.Log("Address:", ygg.GetAddressString())
t.Log("Subnet:", ygg.GetSubnetString())
t.Log("Routing entries:", ygg.GetRoutingEntries())
if err := ygg.Stop(); err != nil {
t.Fatalf("Failed to stop Yggdrasil: %s", err)
}
}
// SendBuffer previously panicked when the caller passed a negative
// length (p[:length] out of range) and Send/SendBuffer with empty
// payload reached writePC, which also panicked.
func TestSendBufferRejectsBadLength(t *testing.T) {
logger := log.New(os.Stdout, "", 0)
ygg := &Yggdrasil{logger: logger}
if err := ygg.StartAutoconfigure(); err != nil {
t.Fatalf("Failed to start Yggdrasil: %s", err)
}
defer func() { _ = ygg.Stop() }()
defer func() {
if r := recover(); r != nil {
t.Fatalf("SendBuffer must not panic on bad length, got: %v", r)
}
}()
if err := ygg.SendBuffer([]byte{1, 2, 3, 4}, -1); err != nil {
t.Fatalf("SendBuffer returned unexpected error: %s", err)
}
if err := ygg.SendBuffer(nil, 0); err != nil {
t.Fatalf("SendBuffer returned unexpected error: %s", err)
}
if err := ygg.Send(nil); err != nil {
t.Fatalf("Send returned unexpected error: %s", err)
}
}