Browse Source

codec: decode struct from encoded array should stay within length of encoded array.

Ugorji Nwoke 12 years ago
parent
commit
b25a055584
3 changed files with 31 additions and 18 deletions
  1. 11 1
      codec/decode.go
  2. 19 16
      codec/encode.go
  3. 1 1
      codec/helper.go

+ 11 - 1
codec/decode.go

@@ -455,13 +455,23 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 				break
 			}
 			sfi := getStructFieldInfos(rtid, rt)
-			for _, si := range sfi.sisp {
+			for j, si := range sfi.sisp {
+				if j == containerLen {
+					break
+				}
 				if si.i != -1 {
 					d.decodeValue(rv.Field(int(si.i)))
 				} else {
 					d.decodeValue(rv.FieldByIndex(si.is))
 				}
 			}
+			if containerLen > len(sfi.sisp) {
+				// read remaining values and throw away
+				for j := len(sfi.sisp); j < containerLen; j++ {
+					var nilintf0 interface{}
+					d.decodeValue(reflect.ValueOf(&nilintf0).Elem())
+				}
+			}
 		} else {
 			decErr("Only encoded map or array can be decoded into a struct")
 		}

+ 19 - 16
codec/encode.go

@@ -216,28 +216,31 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
 
 // Encode writes an object into a stream in the codec format.
 //
+// Encoding can be configured via the "codec" struct tag for the fields.
+// 
+// The "codec" key in struct field's tag value is the key name,
+// followed by an optional comma and options.
+// 
+// To set an option on all fields (e.g. omitempty on all fields), you
+// can create a field called _struct, and set flags on it. 
+// 
 // Struct values "usually" encode as maps. Each exported struct field is encoded unless:
-//    - the field's tag is "-", OR
-//    - the field is empty and its tag specifies the "omitempty" option.
-//
-// However, struct values may encode as arrays. This happens if:
+//    - the field's codec tag is "-", OR
+//    - the field is empty and its codec tag specifies the "omitempty" option.
+// 
+// When encoding as a map, the first string in the tag (before the comma)
+// is the map key string to use when encoding.
+// 
+// However, struct values may encode as arrays. This happens when:
 //    - StructToArray Encode option is set, OR
-//    - the tag on the _struct field sets the "toarray" option
+//    - the codec tag on the _struct field sets the "toarray" option
 // 
-// The empty values are false, 0, any nil pointer or interface value,
-// and any array, slice, map, or string of length zero.
+// The empty values (for omitempty option) are false, 0, any nil pointer 
+// or interface value, and any array, slice, map, or string of length zero.
 //
 // Anonymous fields are encoded inline if no struct tag is present.
 // Else they are encoded as regular fields.
-//
-// The object's default key string is the struct field name but can be
-// specified in the struct field's tag value.
-// The "codec" key in struct field's tag value is the key name,
-// followed by an optional comma and options.
-//
-// To set an option on all fields (e.g. omitempty on all fields), you
-// can create a field called _struct, and set flags on it.
-//
+// 
 // Examples:
 //
 //      type MyStruct struct {

+ 1 - 1
codec/helper.go

@@ -106,9 +106,9 @@ type structFieldInfo struct {
 }
 
 type structFieldInfos struct {
-	toArray bool 
 	sis     []structFieldInfo // sorted. Used when enc/dec struct to map.
 	sisp    []structFieldInfo // unsorted. Used when enc/dec struct to array.
+	toArray bool 
 }
 
 type sfiSortedByEncName []*structFieldInfo