You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

marshal.go 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package rubygems
  4. import (
  5. "bufio"
  6. "bytes"
  7. "io"
  8. "reflect"
  9. "code.gitea.io/gitea/modules/util"
  10. )
  11. const (
  12. majorVersion = 4
  13. minorVersion = 8
  14. typeNil = '0'
  15. typeTrue = 'T'
  16. typeFalse = 'F'
  17. typeFixnum = 'i'
  18. typeString = '"'
  19. typeSymbol = ':'
  20. typeSymbolLink = ';'
  21. typeArray = '['
  22. typeIVar = 'I'
  23. typeUserMarshal = 'U'
  24. typeUserDef = 'u'
  25. typeObject = 'o'
  26. )
  27. var (
  28. // ErrUnsupportedType indicates an unsupported type
  29. ErrUnsupportedType = util.NewInvalidArgumentErrorf("type is unsupported")
  30. // ErrInvalidIntRange indicates an invalid number range
  31. ErrInvalidIntRange = util.NewInvalidArgumentErrorf("number is not in valid range")
  32. )
  33. // RubyUserMarshal is a Ruby object that has a marshal_load function.
  34. type RubyUserMarshal struct {
  35. Name string
  36. Value any
  37. }
  38. // RubyUserDef is a Ruby object that has a _load function.
  39. type RubyUserDef struct {
  40. Name string
  41. Value any
  42. }
  43. // RubyObject is a default Ruby object.
  44. type RubyObject struct {
  45. Name string
  46. Member map[string]any
  47. }
  48. // MarshalEncoder mimics Rubys Marshal class.
  49. // Note: Only supports types used by the RubyGems package registry.
  50. type MarshalEncoder struct {
  51. w *bufio.Writer
  52. symbols map[string]int
  53. }
  54. // NewMarshalEncoder creates a new MarshalEncoder
  55. func NewMarshalEncoder(w io.Writer) *MarshalEncoder {
  56. return &MarshalEncoder{
  57. w: bufio.NewWriter(w),
  58. symbols: map[string]int{},
  59. }
  60. }
  61. // Encode encodes the given type
  62. func (e *MarshalEncoder) Encode(v any) error {
  63. if _, err := e.w.Write([]byte{majorVersion, minorVersion}); err != nil {
  64. return err
  65. }
  66. if err := e.marshal(v); err != nil {
  67. return err
  68. }
  69. return e.w.Flush()
  70. }
  71. func (e *MarshalEncoder) marshal(v any) error {
  72. if v == nil {
  73. return e.marshalNil()
  74. }
  75. val := reflect.ValueOf(v)
  76. typ := reflect.TypeOf(v)
  77. if typ.Kind() == reflect.Ptr {
  78. val = val.Elem()
  79. typ = typ.Elem()
  80. }
  81. switch typ.Kind() {
  82. case reflect.Bool:
  83. return e.marshalBool(val.Bool())
  84. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
  85. return e.marshalInt(val.Int())
  86. case reflect.String:
  87. return e.marshalString(val.String())
  88. case reflect.Slice, reflect.Array:
  89. return e.marshalArray(val)
  90. }
  91. switch typ.Name() {
  92. case "RubyUserMarshal":
  93. return e.marshalUserMarshal(val.Interface().(RubyUserMarshal))
  94. case "RubyUserDef":
  95. return e.marshalUserDef(val.Interface().(RubyUserDef))
  96. case "RubyObject":
  97. return e.marshalObject(val.Interface().(RubyObject))
  98. }
  99. return ErrUnsupportedType
  100. }
  101. func (e *MarshalEncoder) marshalNil() error {
  102. return e.w.WriteByte(typeNil)
  103. }
  104. func (e *MarshalEncoder) marshalBool(b bool) error {
  105. if b {
  106. return e.w.WriteByte(typeTrue)
  107. }
  108. return e.w.WriteByte(typeFalse)
  109. }
  110. func (e *MarshalEncoder) marshalInt(i int64) error {
  111. if err := e.w.WriteByte(typeFixnum); err != nil {
  112. return err
  113. }
  114. return e.marshalIntInternal(i)
  115. }
  116. func (e *MarshalEncoder) marshalIntInternal(i int64) error {
  117. if i == 0 {
  118. return e.w.WriteByte(0)
  119. } else if 0 < i && i < 123 {
  120. return e.w.WriteByte(byte(i + 5))
  121. } else if -124 < i && i <= -1 {
  122. return e.w.WriteByte(byte(i - 5))
  123. }
  124. var length int
  125. if 122 < i && i <= 0xff {
  126. length = 1
  127. } else if 0xff < i && i <= 0xffff {
  128. length = 2
  129. } else if 0xffff < i && i <= 0xffffff {
  130. length = 3
  131. } else if 0xffffff < i && i <= 0x3fffffff {
  132. length = 4
  133. } else if -0x100 <= i && i < -123 {
  134. length = -1
  135. } else if -0x10000 <= i && i < -0x100 {
  136. length = -2
  137. } else if -0x1000000 <= i && i < -0x100000 {
  138. length = -3
  139. } else if -0x40000000 <= i && i < -0x1000000 {
  140. length = -4
  141. } else {
  142. return ErrInvalidIntRange
  143. }
  144. if err := e.w.WriteByte(byte(length)); err != nil {
  145. return err
  146. }
  147. if length < 0 {
  148. length = -length
  149. }
  150. for c := 0; c < length; c++ {
  151. if err := e.w.WriteByte(byte(i >> uint(8*c) & 0xff)); err != nil {
  152. return err
  153. }
  154. }
  155. return nil
  156. }
  157. func (e *MarshalEncoder) marshalString(str string) error {
  158. if err := e.w.WriteByte(typeIVar); err != nil {
  159. return err
  160. }
  161. if err := e.marshalRawString(str); err != nil {
  162. return err
  163. }
  164. if err := e.marshalIntInternal(1); err != nil {
  165. return err
  166. }
  167. if err := e.marshalSymbol("E"); err != nil {
  168. return err
  169. }
  170. return e.marshalBool(true)
  171. }
  172. func (e *MarshalEncoder) marshalRawString(str string) error {
  173. if err := e.w.WriteByte(typeString); err != nil {
  174. return err
  175. }
  176. if err := e.marshalIntInternal(int64(len(str))); err != nil {
  177. return err
  178. }
  179. _, err := e.w.WriteString(str)
  180. return err
  181. }
  182. func (e *MarshalEncoder) marshalSymbol(str string) error {
  183. if index, ok := e.symbols[str]; ok {
  184. if err := e.w.WriteByte(typeSymbolLink); err != nil {
  185. return err
  186. }
  187. return e.marshalIntInternal(int64(index))
  188. }
  189. e.symbols[str] = len(e.symbols)
  190. if err := e.w.WriteByte(typeSymbol); err != nil {
  191. return err
  192. }
  193. if err := e.marshalIntInternal(int64(len(str))); err != nil {
  194. return err
  195. }
  196. _, err := e.w.WriteString(str)
  197. return err
  198. }
  199. func (e *MarshalEncoder) marshalArray(arr reflect.Value) error {
  200. if err := e.w.WriteByte(typeArray); err != nil {
  201. return err
  202. }
  203. length := arr.Len()
  204. if err := e.marshalIntInternal(int64(length)); err != nil {
  205. return err
  206. }
  207. for i := 0; i < length; i++ {
  208. if err := e.marshal(arr.Index(i).Interface()); err != nil {
  209. return err
  210. }
  211. }
  212. return nil
  213. }
  214. func (e *MarshalEncoder) marshalUserMarshal(userMarshal RubyUserMarshal) error {
  215. if err := e.w.WriteByte(typeUserMarshal); err != nil {
  216. return err
  217. }
  218. if err := e.marshalSymbol(userMarshal.Name); err != nil {
  219. return err
  220. }
  221. return e.marshal(userMarshal.Value)
  222. }
  223. func (e *MarshalEncoder) marshalUserDef(userDef RubyUserDef) error {
  224. var buf bytes.Buffer
  225. if err := NewMarshalEncoder(&buf).Encode(userDef.Value); err != nil {
  226. return err
  227. }
  228. if err := e.w.WriteByte(typeUserDef); err != nil {
  229. return err
  230. }
  231. if err := e.marshalSymbol(userDef.Name); err != nil {
  232. return err
  233. }
  234. if err := e.marshalIntInternal(int64(buf.Len())); err != nil {
  235. return err
  236. }
  237. _, err := e.w.Write(buf.Bytes())
  238. return err
  239. }
  240. func (e *MarshalEncoder) marshalObject(obj RubyObject) error {
  241. if err := e.w.WriteByte(typeObject); err != nil {
  242. return err
  243. }
  244. if err := e.marshalSymbol(obj.Name); err != nil {
  245. return err
  246. }
  247. if err := e.marshalIntInternal(int64(len(obj.Member))); err != nil {
  248. return err
  249. }
  250. for k, v := range obj.Member {
  251. if err := e.marshalSymbol(k); err != nil {
  252. return err
  253. }
  254. if err := e.marshal(v); err != nil {
  255. return err
  256. }
  257. }
  258. return nil
  259. }