From 4365628bffc06943d7ae759ea338edc19048c316 Mon Sep 17 00:00:00 2001 From: Unlock Music Dev Date: Sat, 19 Nov 2022 07:25:42 +0800 Subject: [PATCH] refactor: qmc don't export internal functions --- algo/qmc/cipher_map.go | 2 +- algo/qmc/cipher_map_test.go | 2 +- algo/qmc/cipher_rc4.go | 4 ++-- algo/qmc/cipher_rc4_test.go | 10 ++++----- algo/qmc/cipher_static.go | 2 +- algo/qmc/{key_dec.go => key_derive.go} | 2 +- .../{key_dec_test.go => key_derive_test.go} | 6 ++--- algo/qmc/qmc.go | 22 +++++++++---------- 8 files changed, 24 insertions(+), 26 deletions(-) rename algo/qmc/{key_dec.go => key_derive.go} (98%) rename algo/qmc/{key_dec_test.go => key_derive_test.go} (89%) diff --git a/algo/qmc/cipher_map.go b/algo/qmc/cipher_map.go index 56e0626..b73174e 100644 --- a/algo/qmc/cipher_map.go +++ b/algo/qmc/cipher_map.go @@ -8,7 +8,7 @@ type mapCipher struct { size int } -func NewMapCipher(key []byte) (*mapCipher, error) { +func newMapCipher(key []byte) (*mapCipher, error) { if len(key) == 0 { return nil, errors.New("qmc/cipher_map: invalid key size") } diff --git a/algo/qmc/cipher_map_test.go b/algo/qmc/cipher_map_test.go index 400ef94..e478b0d 100644 --- a/algo/qmc/cipher_map_test.go +++ b/algo/qmc/cipher_map_test.go @@ -39,7 +39,7 @@ func Test_mapCipher_Decrypt(t *testing.T) { if err != nil { t.Fatalf("load testing data failed: %s", err) } - c, err := NewMapCipher(key) + c, err := newMapCipher(key) if err != nil { t.Errorf("init mapCipher failed: %s", err) return diff --git a/algo/qmc/cipher_rc4.go b/algo/qmc/cipher_rc4.go index 791d6da..d031d37 100644 --- a/algo/qmc/cipher_rc4.go +++ b/algo/qmc/cipher_rc4.go @@ -12,9 +12,9 @@ type rc4Cipher struct { n int } -// NewRC4Cipher creates and returns a new rc4Cipher. The key argument should be the +// newRC4Cipher creates and returns a new rc4Cipher. The key argument should be the // RC4 key, at least 1 byte and at most 256 bytes. -func NewRC4Cipher(key []byte) (*rc4Cipher, error) { +func newRC4Cipher(key []byte) (*rc4Cipher, error) { n := len(key) if n == 0 { return nil, errors.New("qmc/cipher_rc4: invalid key size") diff --git a/algo/qmc/cipher_rc4_test.go b/algo/qmc/cipher_rc4_test.go index e874ec2..5f2df92 100644 --- a/algo/qmc/cipher_rc4_test.go +++ b/algo/qmc/cipher_rc4_test.go @@ -37,7 +37,7 @@ func Test_rc4Cipher_Decrypt(t *testing.T) { if err != nil { t.Fatalf("load testing data failed: %s", err) } - c, err := NewRC4Cipher(key) + c, err := newRC4Cipher(key) if err != nil { t.Errorf("init rc4Cipher failed: %s", err) return @@ -55,7 +55,7 @@ func BenchmarkRc4Cipher_Decrypt(b *testing.B) { if err != nil { b.Fatalf("load testing data failed: %s", err) } - c, err := NewRC4Cipher(key) + c, err := newRC4Cipher(key) if err != nil { b.Errorf("init rc4Cipher failed: %s", err) return @@ -72,7 +72,7 @@ func Test_rc4Cipher_encFirstSegment(t *testing.T) { t.Fatalf("load testing data failed: %s", err) } t.Run("first-block(0~128)", func(t *testing.T) { - c, err := NewRC4Cipher(key) + c, err := newRC4Cipher(key) if err != nil { t.Errorf("init rc4Cipher failed: %s", err) return @@ -91,7 +91,7 @@ func Test_rc4Cipher_encASegment(t *testing.T) { } t.Run("align-block(128~5120)", func(t *testing.T) { - c, err := NewRC4Cipher(key) + c, err := newRC4Cipher(key) if err != nil { t.Errorf("init rc4Cipher failed: %s", err) return @@ -102,7 +102,7 @@ func Test_rc4Cipher_encASegment(t *testing.T) { } }) t.Run("simple-block(5120~10240)", func(t *testing.T) { - c, err := NewRC4Cipher(key) + c, err := newRC4Cipher(key) if err != nil { t.Errorf("init rc4Cipher failed: %s", err) return diff --git a/algo/qmc/cipher_static.go b/algo/qmc/cipher_static.go index f6db30b..318e191 100644 --- a/algo/qmc/cipher_static.go +++ b/algo/qmc/cipher_static.go @@ -1,6 +1,6 @@ package qmc -func NewStaticCipher() *staticCipher { +func newStaticCipher() *staticCipher { return &defaultStaticCipher } diff --git a/algo/qmc/key_dec.go b/algo/qmc/key_derive.go similarity index 98% rename from algo/qmc/key_dec.go rename to algo/qmc/key_derive.go index efc1ee0..99c3ac9 100644 --- a/algo/qmc/key_dec.go +++ b/algo/qmc/key_derive.go @@ -21,7 +21,7 @@ func simpleMakeKey(salt byte, length int) []byte { const rawKeyPrefixV2 = "QQMusic EncV2,Key:" -func DecryptKey(rawKey []byte) ([]byte, error) { +func deriveKey(rawKey []byte) ([]byte, error) { rawKeyDec := make([]byte, base64.StdEncoding.DecodedLen(len(rawKey))) n, err := base64.StdEncoding.Decode(rawKeyDec, rawKey) if err != nil { diff --git a/algo/qmc/key_dec_test.go b/algo/qmc/key_derive_test.go similarity index 89% rename from algo/qmc/key_dec_test.go rename to algo/qmc/key_derive_test.go index 4ebf8fd..b401692 100644 --- a/algo/qmc/key_dec_test.go +++ b/algo/qmc/key_derive_test.go @@ -43,13 +43,13 @@ func TestDecryptKey(t *testing.T) { if err != nil { t.Fatalf("load test data failed: %s", err) } - got, err := DecryptKey(raw) + got, err := deriveKey(raw) if (err != nil) != tt.wantErr { - t.Errorf("DecryptKey() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("deriveKey() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, want) { - t.Errorf("DecryptKey() got = %v..., want %v...", + t.Errorf("deriveKey() got = %v..., want %v...", string(got[:32]), string(want[:32])) } }) diff --git a/algo/qmc/qmc.go b/algo/qmc/qmc.go index 948d04f..4318946 100644 --- a/algo/qmc/qmc.go +++ b/algo/qmc/qmc.go @@ -28,18 +28,16 @@ type Decoder struct { // Validate should call before Read to check if the file is valid. func (d *Decoder) Read(p []byte) (int, error) { n := len(p) - if d.audioLen-d.offset <= 0 { + if d.audioLen <= d.offset { return 0, io.EOF } else if d.audioLen-d.offset < n { n = d.audioLen - d.offset } m, err := d.r.Read(p[:n]) - if m == 0 { - return 0, err + if m > 0 { + d.cipher.Decrypt(p[:m], d.offset) + d.offset += m } - - d.cipher.Decrypt(p[:m], d.offset) - d.offset += m return m, err } @@ -51,17 +49,17 @@ func NewDecoder(r io.ReadSeeker) (*Decoder, error) { } if len(d.decodedKey) > 300 { - d.cipher, err = NewRC4Cipher(d.decodedKey) + d.cipher, err = newRC4Cipher(d.decodedKey) if err != nil { return nil, err } } else if len(d.decodedKey) != 0 { - d.cipher, err = NewMapCipher(d.decodedKey) + d.cipher, err = newMapCipher(d.decodedKey) if err != nil { return nil, err } } else { - d.cipher = NewStaticCipher() + d.cipher = newStaticCipher() } _, err = d.r.Seek(0, io.SeekStart) @@ -110,7 +108,7 @@ func (d *Decoder) searchKey() error { return errors.New("qmc: file with 'STag' suffix doesn't contains media key") } else { size := binary.LittleEndian.Uint32(buf) - if size < 0x300 && size != 0 { + if size <= 0xFFFF && size != 0 { // assume size is key len return d.readRawKey(int64(size)) } // try to use default static cipher @@ -134,7 +132,7 @@ func (d *Decoder) readRawKey(rawKeyLen int64) error { // clean suffix NULs rawKeyData = bytes.TrimRight(rawKeyData, "\x00") - d.decodedKey, err = DecryptKey(rawKeyData) + d.decodedKey, err = deriveKey(rawKeyData) if err != nil { return err } @@ -169,7 +167,7 @@ func (d *Decoder) readRawMetaQTag() error { return errors.New("invalid raw meta data") } - d.decodedKey, err = DecryptKey([]byte(items[0])) + d.decodedKey, err = deriveKey([]byte(items[0])) if err != nil { return err }