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