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  }