package cliprdr import ( "bytes" "encoding/binary" "strings" "testing" ) func TestEncodeCFHTMLRoundTrip(t *testing.T) { frag := "

红色 加粗

" data := EncodeCFHTML(frag) s := string(data) if !strings.HasPrefix(s, "Version:0.9\r\n") { t.Fatalf("missing version header: %q", s[:30]) } // 固定头长 105 字节,doc 从 105 开始 if !strings.HasPrefix(s[105:], "") { t.Fatalf("html doc should start at offset 105 with wrapper prefix") } // 偏移字段自洽(10 位零填充、字节偏移) expect := func(key string, want int) { i := strings.Index(s, key) if i < 0 { t.Fatalf("missing %s", key) } v := 0 for _, c := range s[i+len(key) : i+len(key)+10] { if c < '0' || c > '9' { t.Fatalf("%s offset not 10-digit: %q", key, s[i+len(key):i+len(key)+10]) } v = v*10 + int(c-'0') } if v != want { t.Fatalf("%s=%d, want %d", key, v, want) } } expect("StartHTML:", 105) expect("EndHTML:", len(data)) expect("StartFragment:", 105+len(cfHTMLWrapPrefix)) expect("EndFragment:", len(data)-len(cfHTMLWrapSuffix)) // 往返 if got := DecodeCFHTML(data); got != frag { t.Fatalf("round-trip mismatch:\n got %q\nwant %q", got, frag) } // 二进制读取不消费编码流(防御:编码流是文本格式) var n uint32 if err := binary.Read(bytes.NewReader(data[:4]), binary.LittleEndian, &n); err != nil { t.Fatalf("binary sanity: %v", err) } } func TestDecodeCFHTMLWindowsSample(t *testing.T) { // 模拟 Windows 剪贴板的实际字节流(头部 + 文档),含 UTF-8 中文 frag := "

hello \xe4\xb8\xad\xe6\x96\x87

" doc := "" + frag + "" var buf bytes.Buffer buf.WriteString("Version:0.9\r\nStartHTML:0000000105\r\n") endHTML := 105 + len(doc) buf.WriteString("EndHTML:" + pad10(endHTML) + "\r\n") startFragment := 105 + len(cfHTMLWrapPrefix) buf.WriteString("StartFragment:" + pad10(startFragment) + "\r\n") endFragment := startFragment + len(frag) buf.WriteString("EndFragment:" + pad10(endFragment) + "\r\n") buf.WriteString(doc) got := DecodeCFHTML(buf.Bytes()) if got != frag { t.Fatalf("decode mismatch:\n got %q\nwant %q", got, frag) } } func TestDecodeCFHTMLFallback(t *testing.T) { // 无有效头的乱数据:回退为原样返回,不得 panic got := DecodeCFHTML([]byte("not a cf_html stream")) if got != "not a cf_html stream" { t.Fatalf("fallback changed content: %q", got) } } func pad10(v int) string { s := itoa10(v) if len(s) > 10 { s = s[len(s)-10:] } for len(s) < 10 { s = "0" + s } return s } func itoa10(v int) string { if v == 0 { return "0" } var b []byte for v > 0 { b = append([]byte{byte('0' + v%10)}, b...) v /= 10 } return string(b) }