strings_test.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package ndr
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "encoding/hex"
  6. "testing"
  7. "github.com/stretchr/testify/assert"
  8. )
  9. const (
  10. TestStr = "hello world!"
  11. TestStrUTF16Hex = "680065006c006c006f00200077006f0072006c00640021000000" // little endian format
  12. )
  13. type TestStructWithVaryingString struct {
  14. A string `ndr:"varying"`
  15. }
  16. type TestStructWithConformantVaryingString struct {
  17. A string `ndr:"conformant,varying"`
  18. }
  19. type TestStructWithConformantVaryingStringUniArray struct {
  20. A []string `ndr:"conformant,varying"`
  21. }
  22. // Should not have to specify varying tag
  23. type TestStructWithNonConformantStringUniArray struct {
  24. A []string
  25. }
  26. type TestStructWithConformantVaryingStringMultiArray struct {
  27. A [][][]string `ndr:"conformant,varying"`
  28. }
  29. // Should not have to specify varying tag
  30. type TestStructWithNonConformantStringMultiArray struct {
  31. A [][][]string
  32. }
  33. // Strings are always varying but the array may not be
  34. type TestStructWithFixedStringUniArray struct {
  35. A [4]string
  36. }
  37. type TestStructWithFixedStringMultiArray struct {
  38. A [2][3][2]string
  39. }
  40. func Test_uint16SliceToString(t *testing.T) {
  41. b, _ := hex.DecodeString(TestStrUTF16Hex)
  42. var u []uint16
  43. for i := 0; i < len(b); i += 2 {
  44. u = append(u, binary.LittleEndian.Uint16(b[i:i+2]))
  45. }
  46. s := uint16SliceToString(u)
  47. assert.Equal(t, TestStr, s, "uint16SliceToString did not return as expected")
  48. }
  49. func Test_readVaryingString(t *testing.T) {
  50. ac := make([]byte, 4, 4)
  51. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  52. hexStr := TestHeader + "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // header:offset(0):actual count:data
  53. b, _ := hex.DecodeString(hexStr)
  54. a := new(TestStructWithVaryingString)
  55. dec := NewDecoder(bytes.NewReader(b))
  56. err := dec.Decode(a)
  57. if err != nil {
  58. t.Fatalf("%v", err)
  59. }
  60. assert.Equal(t, TestStr, a.A, "value of decoded varying string not as expected")
  61. }
  62. func Test_readConformantVaryingString(t *testing.T) {
  63. ac := make([]byte, 4, 4)
  64. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  65. hexStr := TestHeader + hex.EncodeToString(ac) + "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // header:max:offset(0):actual count:data
  66. b, _ := hex.DecodeString(hexStr)
  67. a := new(TestStructWithConformantVaryingString)
  68. dec := NewDecoder(bytes.NewReader(b))
  69. err := dec.Decode(a)
  70. if err != nil {
  71. t.Fatalf("%v", err)
  72. }
  73. assert.Equal(t, TestStr, a.A, "value of decoded varying string not as expected")
  74. }
  75. func Test_readConformantStringUniDimensionalArray(t *testing.T) {
  76. ac := make([]byte, 4, 4)
  77. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  78. hexStr := "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // offset(0):actual count:data
  79. hexStr = TestHeader + "04000000" + hex.EncodeToString(ac) + "0000000004000000" + hexStr + "0000" + hexStr + "0000" + hexStr + "0000" + hexStr // header:1st dimension count(4):max for all strings:offset for 1st dim:actual for 1st dim:string array elements(4) with offset and actual counts. Need to include some bytes for alignment.
  80. b, _ := hex.DecodeString(hexStr)
  81. a := new(TestStructWithConformantVaryingStringUniArray)
  82. dec := NewDecoder(bytes.NewReader(b))
  83. err := dec.Decode(a)
  84. if err != nil {
  85. t.Fatalf("%v", err)
  86. }
  87. assert.Equal(t, 4, len(a.A), "length of string array not as expected")
  88. for _, s := range a.A {
  89. if s != TestStr {
  90. t.Fatalf("string array does not contain the right values")
  91. }
  92. }
  93. }
  94. func Test_readConformantStringMultiDimensionalArray(t *testing.T) {
  95. ac := make([]byte, 4, 4)
  96. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  97. strb := "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // offset(0):actual count:data
  98. var hexStr string
  99. for i := 0; i < 12; i++ {
  100. hexStr = hexStr + strb + "0000"
  101. }
  102. hexStr = TestHeader + "02000000" + "03000000" + "02000000" + hex.EncodeToString(ac) + "0000000002000000" + "0000000003000000" + "0000000002000000" + hexStr
  103. b, _ := hex.DecodeString(hexStr)
  104. a := new(TestStructWithConformantVaryingStringMultiArray)
  105. dec := NewDecoder(bytes.NewReader(b))
  106. err := dec.Decode(a)
  107. if err != nil {
  108. t.Fatalf("%v", err)
  109. }
  110. ar := [][][]string{
  111. {
  112. {TestStr, TestStr},
  113. {TestStr, TestStr},
  114. {TestStr, TestStr},
  115. },
  116. {
  117. {TestStr, TestStr},
  118. {TestStr, TestStr},
  119. {TestStr, TestStr},
  120. },
  121. }
  122. assert.Equal(t, ar, a.A, "fixed multi-dimensional string array not as expected")
  123. }
  124. func Test_readNonConformantStringUniDimensionalArray(t *testing.T) {
  125. ac := make([]byte, 4, 4)
  126. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  127. hexStr := "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // offset(0):actual count:data
  128. hexStr = TestHeader + "0000000004000000" + hexStr + "0000" + hexStr + "0000" + hexStr + "0000" + hexStr // header:offset for 1st dim:actual for 1st dim:string array elements(4) with offset and actual counts. Need to include some bytes for alignment.
  129. b, _ := hex.DecodeString(hexStr)
  130. a := new(TestStructWithNonConformantStringUniArray)
  131. dec := NewDecoder(bytes.NewReader(b))
  132. err := dec.Decode(a)
  133. if err != nil {
  134. t.Fatalf("%v", err)
  135. }
  136. assert.Equal(t, 4, len(a.A), "length of string array not as expected")
  137. for _, s := range a.A {
  138. if s != TestStr {
  139. t.Fatalf("string array does not contain the right values")
  140. }
  141. }
  142. }
  143. func Test_readNonConformantStringMultiDimensionalArray(t *testing.T) {
  144. ac := make([]byte, 4, 4)
  145. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  146. strb := "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // offset(0):actual count:data
  147. var hexStr string
  148. for i := 0; i < 12; i++ {
  149. hexStr = hexStr + strb + "0000"
  150. }
  151. hexStr = TestHeader + "0000000002000000" + "0000000003000000" + "0000000002000000" + hexStr
  152. b, _ := hex.DecodeString(hexStr)
  153. a := new(TestStructWithNonConformantStringMultiArray)
  154. dec := NewDecoder(bytes.NewReader(b))
  155. err := dec.Decode(a)
  156. if err != nil {
  157. t.Fatalf("%v", err)
  158. }
  159. ar := [][][]string{
  160. {
  161. {TestStr, TestStr},
  162. {TestStr, TestStr},
  163. {TestStr, TestStr},
  164. },
  165. {
  166. {TestStr, TestStr},
  167. {TestStr, TestStr},
  168. {TestStr, TestStr},
  169. },
  170. }
  171. assert.Equal(t, ar, a.A, "fixed multi-dimensional string array not as expected")
  172. }
  173. func Test_readFixedStringUniDimensionalArray(t *testing.T) {
  174. ac := make([]byte, 4, 4)
  175. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  176. hexStr := "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // offset(0):actual count:data
  177. hexStr = TestHeader + hexStr + "0000" + hexStr + "0000" + hexStr + "0000" + hexStr // header:offset for 1st dim:actual for 1st dim:string array elements(4) with offset and actual counts. Need to include some bytes for alignment.
  178. b, _ := hex.DecodeString(hexStr)
  179. a := new(TestStructWithFixedStringUniArray)
  180. dec := NewDecoder(bytes.NewReader(b))
  181. err := dec.Decode(a)
  182. if err != nil {
  183. t.Fatalf("%v", err)
  184. }
  185. for _, s := range a.A {
  186. if s != TestStr {
  187. t.Fatalf("string array does not contain the right values")
  188. }
  189. }
  190. }
  191. func Test_readFixedStringMultiDimensionalArray(t *testing.T) {
  192. ac := make([]byte, 4, 4)
  193. binary.LittleEndian.PutUint32(ac, uint32(len(TestStrUTF16Hex)/4)) // actual count of number of uint16 bytes
  194. strb := "00000000" + hex.EncodeToString(ac) + TestStrUTF16Hex // offset(0):actual count:data
  195. var hexStr string
  196. for i := 0; i < 12; i++ {
  197. hexStr = hexStr + strb + "0000"
  198. }
  199. hexStr = TestHeader + hexStr
  200. b, _ := hex.DecodeString(hexStr)
  201. a := new(TestStructWithFixedStringMultiArray)
  202. dec := NewDecoder(bytes.NewReader(b))
  203. err := dec.Decode(a)
  204. if err != nil {
  205. t.Fatalf("%v", err)
  206. }
  207. ar := [2][3][2]string{
  208. {
  209. {TestStr, TestStr},
  210. {TestStr, TestStr},
  211. {TestStr, TestStr},
  212. },
  213. {
  214. {TestStr, TestStr},
  215. {TestStr, TestStr},
  216. {TestStr, TestStr},
  217. },
  218. }
  219. assert.Equal(t, ar, a.A, "fixed multi-dimensional string array not as expected")
  220. }