...

Source file src/gopkg.in/yaml.v2/decode_test.go

Documentation: gopkg.in/yaml.v2

     1  package yaml_test
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"math"
     7  	"reflect"
     8  	"strings"
     9  	"time"
    10  
    11  	. "gopkg.in/check.v1"
    12  	"gopkg.in/yaml.v2"
    13  )
    14  
    15  var unmarshalIntTest = 123
    16  
    17  var unmarshalTests = []struct {
    18  	data  string
    19  	value interface{}
    20  }{
    21  	{
    22  		"",
    23  		(*struct{})(nil),
    24  	},
    25  	{
    26  		"{}", &struct{}{},
    27  	}, {
    28  		"v: hi",
    29  		map[string]string{"v": "hi"},
    30  	}, {
    31  		"v: hi", map[string]interface{}{"v": "hi"},
    32  	}, {
    33  		"v: true",
    34  		map[string]string{"v": "true"},
    35  	}, {
    36  		"v: true",
    37  		map[string]interface{}{"v": true},
    38  	}, {
    39  		"v: 10",
    40  		map[string]interface{}{"v": 10},
    41  	}, {
    42  		"v: 0b10",
    43  		map[string]interface{}{"v": 2},
    44  	}, {
    45  		"v: 0xA",
    46  		map[string]interface{}{"v": 10},
    47  	}, {
    48  		"v: 4294967296",
    49  		map[string]int64{"v": 4294967296},
    50  	}, {
    51  		"v: 0.1",
    52  		map[string]interface{}{"v": 0.1},
    53  	}, {
    54  		"v: .1",
    55  		map[string]interface{}{"v": 0.1},
    56  	}, {
    57  		"v: .Inf",
    58  		map[string]interface{}{"v": math.Inf(+1)},
    59  	}, {
    60  		"v: -.Inf",
    61  		map[string]interface{}{"v": math.Inf(-1)},
    62  	}, {
    63  		"v: -10",
    64  		map[string]interface{}{"v": -10},
    65  	}, {
    66  		"v: -.1",
    67  		map[string]interface{}{"v": -0.1},
    68  	},
    69  
    70  	// Simple values.
    71  	{
    72  		"123",
    73  		&unmarshalIntTest,
    74  	},
    75  
    76  	// Floats from spec
    77  	{
    78  		"canonical: 6.8523e+5",
    79  		map[string]interface{}{"canonical": 6.8523e+5},
    80  	}, {
    81  		"expo: 685.230_15e+03",
    82  		map[string]interface{}{"expo": 685.23015e+03},
    83  	}, {
    84  		"fixed: 685_230.15",
    85  		map[string]interface{}{"fixed": 685230.15},
    86  	}, {
    87  		"neginf: -.inf",
    88  		map[string]interface{}{"neginf": math.Inf(-1)},
    89  	}, {
    90  		"fixed: 685_230.15",
    91  		map[string]float64{"fixed": 685230.15},
    92  	},
    93  	//{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
    94  	//{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
    95  
    96  	// Bools from spec
    97  	{
    98  		"canonical: y",
    99  		map[string]interface{}{"canonical": true},
   100  	}, {
   101  		"answer: NO",
   102  		map[string]interface{}{"answer": false},
   103  	}, {
   104  		"logical: True",
   105  		map[string]interface{}{"logical": true},
   106  	}, {
   107  		"option: on",
   108  		map[string]interface{}{"option": true},
   109  	}, {
   110  		"option: on",
   111  		map[string]bool{"option": true},
   112  	},
   113  	// Ints from spec
   114  	{
   115  		"canonical: 685230",
   116  		map[string]interface{}{"canonical": 685230},
   117  	}, {
   118  		"decimal: +685_230",
   119  		map[string]interface{}{"decimal": 685230},
   120  	}, {
   121  		"octal: 02472256",
   122  		map[string]interface{}{"octal": 685230},
   123  	}, {
   124  		"hexa: 0x_0A_74_AE",
   125  		map[string]interface{}{"hexa": 685230},
   126  	}, {
   127  		"bin: 0b1010_0111_0100_1010_1110",
   128  		map[string]interface{}{"bin": 685230},
   129  	}, {
   130  		"bin: -0b101010",
   131  		map[string]interface{}{"bin": -42},
   132  	}, {
   133  		"bin: -0b1000000000000000000000000000000000000000000000000000000000000000",
   134  		map[string]interface{}{"bin": -9223372036854775808},
   135  	}, {
   136  		"decimal: +685_230",
   137  		map[string]int{"decimal": 685230},
   138  	},
   139  
   140  	//{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
   141  
   142  	// Nulls from spec
   143  	{
   144  		"empty:",
   145  		map[string]interface{}{"empty": nil},
   146  	}, {
   147  		"canonical: ~",
   148  		map[string]interface{}{"canonical": nil},
   149  	}, {
   150  		"english: null",
   151  		map[string]interface{}{"english": nil},
   152  	}, {
   153  		"~: null key",
   154  		map[interface{}]string{nil: "null key"},
   155  	}, {
   156  		"empty:",
   157  		map[string]*bool{"empty": nil},
   158  	},
   159  
   160  	// Flow sequence
   161  	{
   162  		"seq: [A,B]",
   163  		map[string]interface{}{"seq": []interface{}{"A", "B"}},
   164  	}, {
   165  		"seq: [A,B,C,]",
   166  		map[string][]string{"seq": []string{"A", "B", "C"}},
   167  	}, {
   168  		"seq: [A,1,C]",
   169  		map[string][]string{"seq": []string{"A", "1", "C"}},
   170  	}, {
   171  		"seq: [A,1,C]",
   172  		map[string][]int{"seq": []int{1}},
   173  	}, {
   174  		"seq: [A,1,C]",
   175  		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
   176  	},
   177  	// Block sequence
   178  	{
   179  		"seq:\n - A\n - B",
   180  		map[string]interface{}{"seq": []interface{}{"A", "B"}},
   181  	}, {
   182  		"seq:\n - A\n - B\n - C",
   183  		map[string][]string{"seq": []string{"A", "B", "C"}},
   184  	}, {
   185  		"seq:\n - A\n - 1\n - C",
   186  		map[string][]string{"seq": []string{"A", "1", "C"}},
   187  	}, {
   188  		"seq:\n - A\n - 1\n - C",
   189  		map[string][]int{"seq": []int{1}},
   190  	}, {
   191  		"seq:\n - A\n - 1\n - C",
   192  		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
   193  	},
   194  
   195  	// Literal block scalar
   196  	{
   197  		"scalar: | # Comment\n\n literal\n\n \ttext\n\n",
   198  		map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
   199  	},
   200  
   201  	// Folded block scalar
   202  	{
   203  		"scalar: > # Comment\n\n folded\n line\n \n next\n line\n  * one\n  * two\n\n last\n line\n\n",
   204  		map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"},
   205  	},
   206  
   207  	// Map inside interface with no type hints.
   208  	{
   209  		"a: {b: c}",
   210  		map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
   211  	},
   212  
   213  	// Structs and type conversions.
   214  	{
   215  		"hello: world",
   216  		&struct{ Hello string }{"world"},
   217  	}, {
   218  		"a: {b: c}",
   219  		&struct{ A struct{ B string } }{struct{ B string }{"c"}},
   220  	}, {
   221  		"a: {b: c}",
   222  		&struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
   223  	}, {
   224  		"a: {b: c}",
   225  		&struct{ A map[string]string }{map[string]string{"b": "c"}},
   226  	}, {
   227  		"a: {b: c}",
   228  		&struct{ A *map[string]string }{&map[string]string{"b": "c"}},
   229  	}, {
   230  		"a:",
   231  		&struct{ A map[string]string }{},
   232  	}, {
   233  		"a: 1",
   234  		&struct{ A int }{1},
   235  	}, {
   236  		"a: 1",
   237  		&struct{ A float64 }{1},
   238  	}, {
   239  		"a: 1.0",
   240  		&struct{ A int }{1},
   241  	}, {
   242  		"a: 1.0",
   243  		&struct{ A uint }{1},
   244  	}, {
   245  		"a: [1, 2]",
   246  		&struct{ A []int }{[]int{1, 2}},
   247  	}, {
   248  		"a: [1, 2]",
   249  		&struct{ A [2]int }{[2]int{1, 2}},
   250  	}, {
   251  		"a: 1",
   252  		&struct{ B int }{0},
   253  	}, {
   254  		"a: 1",
   255  		&struct {
   256  			B int "a"
   257  		}{1},
   258  	}, {
   259  		"a: y",
   260  		&struct{ A bool }{true},
   261  	},
   262  
   263  	// Some cross type conversions
   264  	{
   265  		"v: 42",
   266  		map[string]uint{"v": 42},
   267  	}, {
   268  		"v: -42",
   269  		map[string]uint{},
   270  	}, {
   271  		"v: 4294967296",
   272  		map[string]uint64{"v": 4294967296},
   273  	}, {
   274  		"v: -4294967296",
   275  		map[string]uint64{},
   276  	},
   277  
   278  	// int
   279  	{
   280  		"int_max: 2147483647",
   281  		map[string]int{"int_max": math.MaxInt32},
   282  	},
   283  	{
   284  		"int_min: -2147483648",
   285  		map[string]int{"int_min": math.MinInt32},
   286  	},
   287  	{
   288  		"int_overflow: 9223372036854775808", // math.MaxInt64 + 1
   289  		map[string]int{},
   290  	},
   291  
   292  	// int64
   293  	{
   294  		"int64_max: 9223372036854775807",
   295  		map[string]int64{"int64_max": math.MaxInt64},
   296  	},
   297  	{
   298  		"int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
   299  		map[string]int64{"int64_max_base2": math.MaxInt64},
   300  	},
   301  	{
   302  		"int64_min: -9223372036854775808",
   303  		map[string]int64{"int64_min": math.MinInt64},
   304  	},
   305  	{
   306  		"int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
   307  		map[string]int64{"int64_neg_base2": -math.MaxInt64},
   308  	},
   309  	{
   310  		"int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
   311  		map[string]int64{},
   312  	},
   313  
   314  	// uint
   315  	{
   316  		"uint_min: 0",
   317  		map[string]uint{"uint_min": 0},
   318  	},
   319  	{
   320  		"uint_max: 4294967295",
   321  		map[string]uint{"uint_max": math.MaxUint32},
   322  	},
   323  	{
   324  		"uint_underflow: -1",
   325  		map[string]uint{},
   326  	},
   327  
   328  	// uint64
   329  	{
   330  		"uint64_min: 0",
   331  		map[string]uint{"uint64_min": 0},
   332  	},
   333  	{
   334  		"uint64_max: 18446744073709551615",
   335  		map[string]uint64{"uint64_max": math.MaxUint64},
   336  	},
   337  	{
   338  		"uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
   339  		map[string]uint64{"uint64_max_base2": math.MaxUint64},
   340  	},
   341  	{
   342  		"uint64_maxint64: 9223372036854775807",
   343  		map[string]uint64{"uint64_maxint64": math.MaxInt64},
   344  	},
   345  	{
   346  		"uint64_underflow: -1",
   347  		map[string]uint64{},
   348  	},
   349  
   350  	// float32
   351  	{
   352  		"float32_max: 3.40282346638528859811704183484516925440e+38",
   353  		map[string]float32{"float32_max": math.MaxFloat32},
   354  	},
   355  	{
   356  		"float32_nonzero: 1.401298464324817070923729583289916131280e-45",
   357  		map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32},
   358  	},
   359  	{
   360  		"float32_maxuint64: 18446744073709551615",
   361  		map[string]float32{"float32_maxuint64": float32(math.MaxUint64)},
   362  	},
   363  	{
   364  		"float32_maxuint64+1: 18446744073709551616",
   365  		map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)},
   366  	},
   367  
   368  	// float64
   369  	{
   370  		"float64_max: 1.797693134862315708145274237317043567981e+308",
   371  		map[string]float64{"float64_max": math.MaxFloat64},
   372  	},
   373  	{
   374  		"float64_nonzero: 4.940656458412465441765687928682213723651e-324",
   375  		map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64},
   376  	},
   377  	{
   378  		"float64_maxuint64: 18446744073709551615",
   379  		map[string]float64{"float64_maxuint64": float64(math.MaxUint64)},
   380  	},
   381  	{
   382  		"float64_maxuint64+1: 18446744073709551616",
   383  		map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)},
   384  	},
   385  
   386  	// Overflow cases.
   387  	{
   388  		"v: 4294967297",
   389  		map[string]int32{},
   390  	}, {
   391  		"v: 128",
   392  		map[string]int8{},
   393  	},
   394  
   395  	// Quoted values.
   396  	{
   397  		"'1': '\"2\"'",
   398  		map[interface{}]interface{}{"1": "\"2\""},
   399  	}, {
   400  		"v:\n- A\n- 'B\n\n  C'\n",
   401  		map[string][]string{"v": []string{"A", "B\nC"}},
   402  	},
   403  
   404  	// Explicit tags.
   405  	{
   406  		"v: !!float '1.1'",
   407  		map[string]interface{}{"v": 1.1},
   408  	}, {
   409  		"v: !!float 0",
   410  		map[string]interface{}{"v": float64(0)},
   411  	}, {
   412  		"v: !!float -1",
   413  		map[string]interface{}{"v": float64(-1)},
   414  	}, {
   415  		"v: !!null ''",
   416  		map[string]interface{}{"v": nil},
   417  	}, {
   418  		"%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
   419  		map[string]interface{}{"v": 1},
   420  	},
   421  
   422  	// Non-specific tag (Issue #75)
   423  	{
   424  		"v: ! test",
   425  		map[string]interface{}{"v": "test"},
   426  	},
   427  
   428  	// Anchors and aliases.
   429  	{
   430  		"a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
   431  		&struct{ A, B, C, D int }{1, 2, 1, 2},
   432  	}, {
   433  		"a: &a {c: 1}\nb: *a",
   434  		&struct {
   435  			A, B struct {
   436  				C int
   437  			}
   438  		}{struct{ C int }{1}, struct{ C int }{1}},
   439  	}, {
   440  		"a: &a [1, 2]\nb: *a",
   441  		&struct{ B []int }{[]int{1, 2}},
   442  	},
   443  
   444  	// Bug #1133337
   445  	{
   446  		"foo: ''",
   447  		map[string]*string{"foo": new(string)},
   448  	}, {
   449  		"foo: null",
   450  		map[string]*string{"foo": nil},
   451  	}, {
   452  		"foo: null",
   453  		map[string]string{"foo": ""},
   454  	}, {
   455  		"foo: null",
   456  		map[string]interface{}{"foo": nil},
   457  	},
   458  
   459  	// Support for ~
   460  	{
   461  		"foo: ~",
   462  		map[string]*string{"foo": nil},
   463  	}, {
   464  		"foo: ~",
   465  		map[string]string{"foo": ""},
   466  	}, {
   467  		"foo: ~",
   468  		map[string]interface{}{"foo": nil},
   469  	},
   470  
   471  	// Ignored field
   472  	{
   473  		"a: 1\nb: 2\n",
   474  		&struct {
   475  			A int
   476  			B int "-"
   477  		}{1, 0},
   478  	},
   479  
   480  	// Bug #1191981
   481  	{
   482  		"" +
   483  			"%YAML 1.1\n" +
   484  			"--- !!str\n" +
   485  			`"Generic line break (no glyph)\n\` + "\n" +
   486  			` Generic line break (glyphed)\n\` + "\n" +
   487  			` Line separator\u2028\` + "\n" +
   488  			` Paragraph separator\u2029"` + "\n",
   489  		"" +
   490  			"Generic line break (no glyph)\n" +
   491  			"Generic line break (glyphed)\n" +
   492  			"Line separator\u2028Paragraph separator\u2029",
   493  	},
   494  
   495  	// Struct inlining
   496  	{
   497  		"a: 1\nb: 2\nc: 3\n",
   498  		&struct {
   499  			A int
   500  			C inlineB `yaml:",inline"`
   501  		}{1, inlineB{2, inlineC{3}}},
   502  	},
   503  
   504  	// Map inlining
   505  	{
   506  		"a: 1\nb: 2\nc: 3\n",
   507  		&struct {
   508  			A int
   509  			C map[string]int `yaml:",inline"`
   510  		}{1, map[string]int{"b": 2, "c": 3}},
   511  	},
   512  
   513  	// bug 1243827
   514  	{
   515  		"a: -b_c",
   516  		map[string]interface{}{"a": "-b_c"},
   517  	},
   518  	{
   519  		"a: +b_c",
   520  		map[string]interface{}{"a": "+b_c"},
   521  	},
   522  	{
   523  		"a: 50cent_of_dollar",
   524  		map[string]interface{}{"a": "50cent_of_dollar"},
   525  	},
   526  
   527  	// issue #295 (allow scalars with colons in flow mappings and sequences)
   528  	{
   529  		"a: {b: https://github.com/go-yaml/yaml}",
   530  		map[string]interface{}{"a": map[interface{}]interface{}{
   531  			"b": "https://github.com/go-yaml/yaml",
   532  		}},
   533  	},
   534  	{
   535  		"a: [https://github.com/go-yaml/yaml]",
   536  		map[string]interface{}{"a": []interface{}{"https://github.com/go-yaml/yaml"}},
   537  	},
   538  
   539  	// Duration
   540  	{
   541  		"a: 3s",
   542  		map[string]time.Duration{"a": 3 * time.Second},
   543  	},
   544  
   545  	// Issue #24.
   546  	{
   547  		"a: <foo>",
   548  		map[string]string{"a": "<foo>"},
   549  	},
   550  
   551  	// Base 60 floats are obsolete and unsupported.
   552  	{
   553  		"a: 1:1\n",
   554  		map[string]string{"a": "1:1"},
   555  	},
   556  
   557  	// Binary data.
   558  	{
   559  		"a: !!binary gIGC\n",
   560  		map[string]string{"a": "\x80\x81\x82"},
   561  	}, {
   562  		"a: !!binary |\n  " + strings.Repeat("kJCQ", 17) + "kJ\n  CQ\n",
   563  		map[string]string{"a": strings.Repeat("\x90", 54)},
   564  	}, {
   565  		"a: !!binary |\n  " + strings.Repeat("A", 70) + "\n  ==\n",
   566  		map[string]string{"a": strings.Repeat("\x00", 52)},
   567  	},
   568  
   569  	// Ordered maps.
   570  	{
   571  		"{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}",
   572  		&yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
   573  	},
   574  
   575  	// Issue #39.
   576  	{
   577  		"a:\n b:\n  c: d\n",
   578  		map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}},
   579  	},
   580  
   581  	// Custom map type.
   582  	{
   583  		"a: {b: c}",
   584  		M{"a": M{"b": "c"}},
   585  	},
   586  
   587  	// Support encoding.TextUnmarshaler.
   588  	{
   589  		"a: 1.2.3.4\n",
   590  		map[string]textUnmarshaler{"a": textUnmarshaler{S: "1.2.3.4"}},
   591  	},
   592  	{
   593  		"a: 2015-02-24T18:19:39Z\n",
   594  		map[string]textUnmarshaler{"a": textUnmarshaler{"2015-02-24T18:19:39Z"}},
   595  	},
   596  
   597  	// Timestamps
   598  	{
   599  		// Date only.
   600  		"a: 2015-01-01\n",
   601  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   602  	},
   603  	{
   604  		// RFC3339
   605  		"a: 2015-02-24T18:19:39.12Z\n",
   606  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)},
   607  	},
   608  	{
   609  		// RFC3339 with short dates.
   610  		"a: 2015-2-3T3:4:5Z",
   611  		map[string]time.Time{"a": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)},
   612  	},
   613  	{
   614  		// ISO8601 lower case t
   615  		"a: 2015-02-24t18:19:39Z\n",
   616  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
   617  	},
   618  	{
   619  		// space separate, no time zone
   620  		"a: 2015-02-24 18:19:39\n",
   621  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
   622  	},
   623  	// Some cases not currently handled. Uncomment these when
   624  	// the code is fixed.
   625  	//	{
   626  	//		// space separated with time zone
   627  	//		"a: 2001-12-14 21:59:43.10 -5",
   628  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   629  	//	},
   630  	//	{
   631  	//		// arbitrary whitespace between fields
   632  	//		"a: 2001-12-14 \t\t \t21:59:43.10 \t Z",
   633  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   634  	//	},
   635  	{
   636  		// explicit string tag
   637  		"a: !!str 2015-01-01",
   638  		map[string]interface{}{"a": "2015-01-01"},
   639  	},
   640  	{
   641  		// explicit timestamp tag on quoted string
   642  		"a: !!timestamp \"2015-01-01\"",
   643  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   644  	},
   645  	{
   646  		// explicit timestamp tag on unquoted string
   647  		"a: !!timestamp 2015-01-01",
   648  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   649  	},
   650  	{
   651  		// quoted string that's a valid timestamp
   652  		"a: \"2015-01-01\"",
   653  		map[string]interface{}{"a": "2015-01-01"},
   654  	},
   655  	{
   656  		// explicit timestamp tag into interface.
   657  		"a: !!timestamp \"2015-01-01\"",
   658  		map[string]interface{}{"a": "2015-01-01"},
   659  	},
   660  	{
   661  		// implicit timestamp tag into interface.
   662  		"a: 2015-01-01",
   663  		map[string]interface{}{"a": "2015-01-01"},
   664  	},
   665  
   666  	// Encode empty lists as zero-length slices.
   667  	{
   668  		"a: []",
   669  		&struct{ A []int }{[]int{}},
   670  	},
   671  
   672  	// UTF-16-LE
   673  	{
   674  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
   675  		M{"ñoño": "very yes"},
   676  	},
   677  	// UTF-16-LE with surrogate.
   678  	{
   679  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
   680  		M{"ñoño": "very yes 🟔"},
   681  	},
   682  
   683  	// UTF-16-BE
   684  	{
   685  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
   686  		M{"ñoño": "very yes"},
   687  	},
   688  	// UTF-16-BE with surrogate.
   689  	{
   690  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
   691  		M{"ñoño": "very yes 🟔"},
   692  	},
   693  
   694  	// This *is* in fact a float number, per the spec. #171 was a mistake.
   695  	{
   696  		"a: 123456e1\n",
   697  		M{"a": 123456e1},
   698  	}, {
   699  		"a: 123456E1\n",
   700  		M{"a": 123456E1},
   701  	},
   702  	// yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes
   703  	{
   704  		"First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n",
   705  		map[interface{}]interface{}{
   706  			"Reuse anchor":      "Bar",
   707  			"First occurrence":  "Foo",
   708  			"Second occurrence": "Foo",
   709  			"Override anchor":   "Bar",
   710  		},
   711  	},
   712  	// Single document with garbage following it.
   713  	{
   714  		"---\nhello\n...\n}not yaml",
   715  		"hello",
   716  	},
   717  	{
   718  		"a: 5\n",
   719  		&struct{ A jsonNumberT }{"5"},
   720  	},
   721  	{
   722  		"a: 5.5\n",
   723  		&struct{ A jsonNumberT }{"5.5"},
   724  	},
   725  	{
   726  		`
   727  a:
   728    b
   729  b:
   730    ? a
   731    : a`,
   732  		&M{"a": "b",
   733  			"b": M{
   734  				"a": "a",
   735  			}},
   736  	},
   737  }
   738  
   739  type M map[interface{}]interface{}
   740  
   741  type inlineB struct {
   742  	B       int
   743  	inlineC `yaml:",inline"`
   744  }
   745  
   746  type inlineC struct {
   747  	C int
   748  }
   749  
   750  func (s *S) TestUnmarshal(c *C) {
   751  	for i, item := range unmarshalTests {
   752  		c.Logf("test %d: %q", i, item.data)
   753  		t := reflect.ValueOf(item.value).Type()
   754  		value := reflect.New(t)
   755  		err := yaml.Unmarshal([]byte(item.data), value.Interface())
   756  		if _, ok := err.(*yaml.TypeError); !ok {
   757  			c.Assert(err, IsNil)
   758  		}
   759  		c.Assert(value.Elem().Interface(), DeepEquals, item.value, Commentf("error: %v", err))
   760  	}
   761  }
   762  
   763  // TODO(v3): This test should also work when unmarshaling onto an interface{}.
   764  func (s *S) TestUnmarshalFullTimestamp(c *C) {
   765  	// Full timestamp in same format as encoded. This is confirmed to be
   766  	// properly decoded by Python as a timestamp as well.
   767  	var str = "2015-02-24T18:19:39.123456789-03:00"
   768  	var t time.Time
   769  	err := yaml.Unmarshal([]byte(str), &t)
   770  	c.Assert(err, IsNil)
   771  	c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location()))
   772  	c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC))
   773  }
   774  
   775  func (s *S) TestDecoderSingleDocument(c *C) {
   776  	// Test that Decoder.Decode works as expected on
   777  	// all the unmarshal tests.
   778  	for i, item := range unmarshalTests {
   779  		c.Logf("test %d: %q", i, item.data)
   780  		if item.data == "" {
   781  			// Behaviour differs when there's no YAML.
   782  			continue
   783  		}
   784  		t := reflect.ValueOf(item.value).Type()
   785  		value := reflect.New(t)
   786  		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(value.Interface())
   787  		if _, ok := err.(*yaml.TypeError); !ok {
   788  			c.Assert(err, IsNil)
   789  		}
   790  		c.Assert(value.Elem().Interface(), DeepEquals, item.value)
   791  	}
   792  }
   793  
   794  var decoderTests = []struct {
   795  	data   string
   796  	values []interface{}
   797  }{{
   798  	"",
   799  	nil,
   800  }, {
   801  	"a: b",
   802  	[]interface{}{
   803  		map[interface{}]interface{}{"a": "b"},
   804  	},
   805  }, {
   806  	"---\na: b\n...\n",
   807  	[]interface{}{
   808  		map[interface{}]interface{}{"a": "b"},
   809  	},
   810  }, {
   811  	"---\n'hello'\n...\n---\ngoodbye\n...\n",
   812  	[]interface{}{
   813  		"hello",
   814  		"goodbye",
   815  	},
   816  }}
   817  
   818  func (s *S) TestDecoder(c *C) {
   819  	for i, item := range decoderTests {
   820  		c.Logf("test %d: %q", i, item.data)
   821  		var values []interface{}
   822  		dec := yaml.NewDecoder(strings.NewReader(item.data))
   823  		for {
   824  			var value interface{}
   825  			err := dec.Decode(&value)
   826  			if err == io.EOF {
   827  				break
   828  			}
   829  			c.Assert(err, IsNil)
   830  			values = append(values, value)
   831  		}
   832  		c.Assert(values, DeepEquals, item.values)
   833  	}
   834  }
   835  
   836  type errReader struct{}
   837  
   838  func (errReader) Read([]byte) (int, error) {
   839  	return 0, errors.New("some read error")
   840  }
   841  
   842  func (s *S) TestDecoderReadError(c *C) {
   843  	err := yaml.NewDecoder(errReader{}).Decode(&struct{}{})
   844  	c.Assert(err, ErrorMatches, `yaml: input error: some read error`)
   845  }
   846  
   847  func (s *S) TestUnmarshalNaN(c *C) {
   848  	value := map[string]interface{}{}
   849  	err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
   850  	c.Assert(err, IsNil)
   851  	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
   852  }
   853  
   854  var unmarshalErrorTests = []struct {
   855  	data, error string
   856  }{
   857  	{"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
   858  	{"v: [A,", "yaml: line 1: did not find expected node content"},
   859  	{"v:\n- [A,", "yaml: line 2: did not find expected node content"},
   860  	{"a:\n- b: *,", "yaml: line 2: did not find expected alphabetic or numeric character"},
   861  	{"a: *b\n", "yaml: unknown anchor 'b' referenced"},
   862  	{"a: &a\n  b: *a\n", "yaml: anchor 'a' value contains itself"},
   863  	{"a: &x null\n<<:\n- *x\nb: &x {}\n", `yaml: map merge requires map or sequence of maps as the value`}, // Issue #529.
   864  	{"value: -", "yaml: block sequence entries are not allowed in this context"},
   865  	{"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
   866  	{"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
   867  	{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
   868  	{"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
   869  	{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
   870  	{"a:\n  1:\nb\n  2:", ".*could not find expected ':'"},
   871  	{
   872  		"a: &a [00,00,00,00,00,00,00,00,00]\n" +
   873  		"b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" +
   874  		"c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]\n" +
   875  		"d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]\n" +
   876  		"e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]\n" +
   877  		"f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]\n" +
   878  		"g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]\n" +
   879  		"h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]\n" +
   880  		"i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]\n",
   881  		"yaml: document contains excessive aliasing",
   882  	},
   883  }
   884  
   885  func (s *S) TestUnmarshalErrors(c *C) {
   886  	for i, item := range unmarshalErrorTests {
   887  		c.Logf("test %d: %q", i, item.data)
   888  		var value interface{}
   889  		err := yaml.Unmarshal([]byte(item.data), &value)
   890  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   891  
   892  		if strings.Contains(item.data, ":") {
   893  			// Repeat test with typed value.
   894  			var value map[string]interface{}
   895  			err := yaml.Unmarshal([]byte(item.data), &value)
   896  			c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   897  		}
   898  	}
   899  }
   900  
   901  func (s *S) TestDecoderErrors(c *C) {
   902  	for _, item := range unmarshalErrorTests {
   903  		var value interface{}
   904  		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(&value)
   905  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   906  	}
   907  }
   908  
   909  var unmarshalerTests = []struct {
   910  	data, tag string
   911  	value     interface{}
   912  }{
   913  	{"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
   914  	{"_: [1,A]", "!!seq", []interface{}{1, "A"}},
   915  	{"_: 10", "!!int", 10},
   916  	{"_: null", "!!null", nil},
   917  	{`_: BAR!`, "!!str", "BAR!"},
   918  	{`_: "BAR!"`, "!!str", "BAR!"},
   919  	{"_: !!foo 'BAR!'", "!!foo", "BAR!"},
   920  	{`_: ""`, "!!str", ""},
   921  }
   922  
   923  var unmarshalerResult = map[int]error{}
   924  
   925  type unmarshalerType struct {
   926  	value interface{}
   927  }
   928  
   929  func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
   930  	if err := unmarshal(&o.value); err != nil {
   931  		return err
   932  	}
   933  	if i, ok := o.value.(int); ok {
   934  		if result, ok := unmarshalerResult[i]; ok {
   935  			return result
   936  		}
   937  	}
   938  	return nil
   939  }
   940  
   941  type unmarshalerPointer struct {
   942  	Field *unmarshalerType "_"
   943  }
   944  
   945  type unmarshalerValue struct {
   946  	Field unmarshalerType "_"
   947  }
   948  
   949  func (s *S) TestUnmarshalerPointerField(c *C) {
   950  	for _, item := range unmarshalerTests {
   951  		obj := &unmarshalerPointer{}
   952  		err := yaml.Unmarshal([]byte(item.data), obj)
   953  		c.Assert(err, IsNil)
   954  		if item.value == nil {
   955  			c.Assert(obj.Field, IsNil)
   956  		} else {
   957  			c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
   958  			c.Assert(obj.Field.value, DeepEquals, item.value)
   959  		}
   960  	}
   961  }
   962  
   963  func (s *S) TestUnmarshalerValueField(c *C) {
   964  	for _, item := range unmarshalerTests {
   965  		obj := &unmarshalerValue{}
   966  		err := yaml.Unmarshal([]byte(item.data), obj)
   967  		c.Assert(err, IsNil)
   968  		c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
   969  		c.Assert(obj.Field.value, DeepEquals, item.value)
   970  	}
   971  }
   972  
   973  func (s *S) TestUnmarshalerWholeDocument(c *C) {
   974  	obj := &unmarshalerType{}
   975  	err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
   976  	c.Assert(err, IsNil)
   977  	value, ok := obj.value.(map[interface{}]interface{})
   978  	c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
   979  	c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
   980  }
   981  
   982  func (s *S) TestUnmarshalerTypeError(c *C) {
   983  	unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
   984  	unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
   985  	defer func() {
   986  		delete(unmarshalerResult, 2)
   987  		delete(unmarshalerResult, 4)
   988  	}()
   989  
   990  	type T struct {
   991  		Before int
   992  		After  int
   993  		M      map[string]*unmarshalerType
   994  	}
   995  	var v T
   996  	data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
   997  	err := yaml.Unmarshal([]byte(data), &v)
   998  	c.Assert(err, ErrorMatches, ""+
   999  		"yaml: unmarshal errors:\n"+
  1000  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1001  		"  foo\n"+
  1002  		"  bar\n"+
  1003  		"  line 1: cannot unmarshal !!str `B` into int")
  1004  	c.Assert(v.M["abc"], NotNil)
  1005  	c.Assert(v.M["def"], IsNil)
  1006  	c.Assert(v.M["ghi"], NotNil)
  1007  	c.Assert(v.M["jkl"], IsNil)
  1008  
  1009  	c.Assert(v.M["abc"].value, Equals, 1)
  1010  	c.Assert(v.M["ghi"].value, Equals, 3)
  1011  }
  1012  
  1013  type proxyTypeError struct{}
  1014  
  1015  func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1016  	var s string
  1017  	var a int32
  1018  	var b int64
  1019  	if err := unmarshal(&s); err != nil {
  1020  		panic(err)
  1021  	}
  1022  	if s == "a" {
  1023  		if err := unmarshal(&b); err == nil {
  1024  			panic("should have failed")
  1025  		}
  1026  		return unmarshal(&a)
  1027  	}
  1028  	if err := unmarshal(&a); err == nil {
  1029  		panic("should have failed")
  1030  	}
  1031  	return unmarshal(&b)
  1032  }
  1033  
  1034  func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
  1035  	type T struct {
  1036  		Before int
  1037  		After  int
  1038  		M      map[string]*proxyTypeError
  1039  	}
  1040  	var v T
  1041  	data := `{before: A, m: {abc: a, def: b}, after: B}`
  1042  	err := yaml.Unmarshal([]byte(data), &v)
  1043  	c.Assert(err, ErrorMatches, ""+
  1044  		"yaml: unmarshal errors:\n"+
  1045  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1046  		"  line 1: cannot unmarshal !!str `a` into int32\n"+
  1047  		"  line 1: cannot unmarshal !!str `b` into int64\n"+
  1048  		"  line 1: cannot unmarshal !!str `B` into int")
  1049  }
  1050  
  1051  type failingUnmarshaler struct{}
  1052  
  1053  var failingErr = errors.New("failingErr")
  1054  
  1055  func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1056  	return failingErr
  1057  }
  1058  
  1059  func (s *S) TestUnmarshalerError(c *C) {
  1060  	err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
  1061  	c.Assert(err, Equals, failingErr)
  1062  }
  1063  
  1064  type sliceUnmarshaler []int
  1065  
  1066  func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1067  	var slice []int
  1068  	err := unmarshal(&slice)
  1069  	if err == nil {
  1070  		*su = slice
  1071  		return nil
  1072  	}
  1073  
  1074  	var intVal int
  1075  	err = unmarshal(&intVal)
  1076  	if err == nil {
  1077  		*su = []int{intVal}
  1078  		return nil
  1079  	}
  1080  
  1081  	return err
  1082  }
  1083  
  1084  func (s *S) TestUnmarshalerRetry(c *C) {
  1085  	var su sliceUnmarshaler
  1086  	err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
  1087  	c.Assert(err, IsNil)
  1088  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
  1089  
  1090  	err = yaml.Unmarshal([]byte("1"), &su)
  1091  	c.Assert(err, IsNil)
  1092  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
  1093  }
  1094  
  1095  // From http://yaml.org/type/merge.html
  1096  var mergeTests = `
  1097  anchors:
  1098    list:
  1099      - &CENTER { "x": 1, "y": 2 }
  1100      - &LEFT   { "x": 0, "y": 2 }
  1101      - &BIG    { "r": 10 }
  1102      - &SMALL  { "r": 1 }
  1103  
  1104  # All the following maps are equal:
  1105  
  1106  plain:
  1107    # Explicit keys
  1108    "x": 1
  1109    "y": 2
  1110    "r": 10
  1111    label: center/big
  1112  
  1113  mergeOne:
  1114    # Merge one map
  1115    << : *CENTER
  1116    "r": 10
  1117    label: center/big
  1118  
  1119  mergeMultiple:
  1120    # Merge multiple maps
  1121    << : [ *CENTER, *BIG ]
  1122    label: center/big
  1123  
  1124  override:
  1125    # Override
  1126    << : [ *BIG, *LEFT, *SMALL ]
  1127    "x": 1
  1128    label: center/big
  1129  
  1130  shortTag:
  1131    # Explicit short merge tag
  1132    !!merge "<<" : [ *CENTER, *BIG ]
  1133    label: center/big
  1134  
  1135  longTag:
  1136    # Explicit merge long tag
  1137    !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
  1138    label: center/big
  1139  
  1140  inlineMap:
  1141    # Inlined map 
  1142    << : {"x": 1, "y": 2, "r": 10}
  1143    label: center/big
  1144  
  1145  inlineSequenceMap:
  1146    # Inlined map in sequence
  1147    << : [ *CENTER, {"r": 10} ]
  1148    label: center/big
  1149  `
  1150  
  1151  func (s *S) TestMerge(c *C) {
  1152  	var want = map[interface{}]interface{}{
  1153  		"x":     1,
  1154  		"y":     2,
  1155  		"r":     10,
  1156  		"label": "center/big",
  1157  	}
  1158  
  1159  	var m map[interface{}]interface{}
  1160  	err := yaml.Unmarshal([]byte(mergeTests), &m)
  1161  	c.Assert(err, IsNil)
  1162  	for name, test := range m {
  1163  		if name == "anchors" {
  1164  			continue
  1165  		}
  1166  		c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
  1167  	}
  1168  }
  1169  
  1170  func (s *S) TestMergeStruct(c *C) {
  1171  	type Data struct {
  1172  		X, Y, R int
  1173  		Label   string
  1174  	}
  1175  	want := Data{1, 2, 10, "center/big"}
  1176  
  1177  	var m map[string]Data
  1178  	err := yaml.Unmarshal([]byte(mergeTests), &m)
  1179  	c.Assert(err, IsNil)
  1180  	for name, test := range m {
  1181  		if name == "anchors" {
  1182  			continue
  1183  		}
  1184  		c.Assert(test, Equals, want, Commentf("test %q failed", name))
  1185  	}
  1186  }
  1187  
  1188  var unmarshalNullTests = []func() interface{}{
  1189  	func() interface{} { var v interface{}; v = "v"; return &v },
  1190  	func() interface{} { var s = "s"; return &s },
  1191  	func() interface{} { var s = "s"; sptr := &s; return &sptr },
  1192  	func() interface{} { var i = 1; return &i },
  1193  	func() interface{} { var i = 1; iptr := &i; return &iptr },
  1194  	func() interface{} { m := map[string]int{"s": 1}; return &m },
  1195  	func() interface{} { m := map[string]int{"s": 1}; return m },
  1196  }
  1197  
  1198  func (s *S) TestUnmarshalNull(c *C) {
  1199  	for _, test := range unmarshalNullTests {
  1200  		item := test()
  1201  		zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
  1202  		err := yaml.Unmarshal([]byte("null"), item)
  1203  		c.Assert(err, IsNil)
  1204  		if reflect.TypeOf(item).Kind() == reflect.Map {
  1205  			c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
  1206  		} else {
  1207  			c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
  1208  		}
  1209  	}
  1210  }
  1211  
  1212  func (s *S) TestUnmarshalSliceOnPreset(c *C) {
  1213  	// Issue #48.
  1214  	v := struct{ A []int }{[]int{1}}
  1215  	yaml.Unmarshal([]byte("a: [2]"), &v)
  1216  	c.Assert(v.A, DeepEquals, []int{2})
  1217  }
  1218  
  1219  var unmarshalStrictTests = []struct {
  1220  	data  string
  1221  	value interface{}
  1222  	error string
  1223  }{{
  1224  	data:  "a: 1\nc: 2\n",
  1225  	value: struct{ A, B int }{A: 1},
  1226  	error: `yaml: unmarshal errors:\n  line 2: field c not found in type struct { A int; B int }`,
  1227  }, {
  1228  	data:  "a: 1\nb: 2\na: 3\n",
  1229  	value: struct{ A, B int }{A: 3, B: 2},
  1230  	error: `yaml: unmarshal errors:\n  line 3: field a already set in type struct { A int; B int }`,
  1231  }, {
  1232  	data: "c: 3\na: 1\nb: 2\nc: 4\n",
  1233  	value: struct {
  1234  		A       int
  1235  		inlineB `yaml:",inline"`
  1236  	}{
  1237  		A: 1,
  1238  		inlineB: inlineB{
  1239  			B: 2,
  1240  			inlineC: inlineC{
  1241  				C: 4,
  1242  			},
  1243  		},
  1244  	},
  1245  	error: `yaml: unmarshal errors:\n  line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`,
  1246  }, {
  1247  	data: "c: 0\na: 1\nb: 2\nc: 1\n",
  1248  	value: struct {
  1249  		A       int
  1250  		inlineB `yaml:",inline"`
  1251  	}{
  1252  		A: 1,
  1253  		inlineB: inlineB{
  1254  			B: 2,
  1255  			inlineC: inlineC{
  1256  				C: 1,
  1257  			},
  1258  		},
  1259  	},
  1260  	error: `yaml: unmarshal errors:\n  line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`,
  1261  }, {
  1262  	data: "c: 1\na: 1\nb: 2\nc: 3\n",
  1263  	value: struct {
  1264  		A int
  1265  		M map[string]interface{} `yaml:",inline"`
  1266  	}{
  1267  		A: 1,
  1268  		M: map[string]interface{}{
  1269  			"b": 2,
  1270  			"c": 3,
  1271  		},
  1272  	},
  1273  	error: `yaml: unmarshal errors:\n  line 4: key "c" already set in map`,
  1274  }, {
  1275  	data: "a: 1\n9: 2\nnull: 3\n9: 4",
  1276  	value: map[interface{}]interface{}{
  1277  		"a": 1,
  1278  		nil: 3,
  1279  		9:   4,
  1280  	},
  1281  	error: `yaml: unmarshal errors:\n  line 4: key 9 already set in map`,
  1282  }}
  1283  
  1284  func (s *S) TestUnmarshalStrict(c *C) {
  1285  	for i, item := range unmarshalStrictTests {
  1286  		c.Logf("test %d: %q", i, item.data)
  1287  		// First test that normal Unmarshal unmarshals to the expected value.
  1288  		t := reflect.ValueOf(item.value).Type()
  1289  		value := reflect.New(t)
  1290  		err := yaml.Unmarshal([]byte(item.data), value.Interface())
  1291  		c.Assert(err, Equals, nil)
  1292  		c.Assert(value.Elem().Interface(), DeepEquals, item.value)
  1293  
  1294  		// Then test that UnmarshalStrict fails on the same thing.
  1295  		t = reflect.ValueOf(item.value).Type()
  1296  		value = reflect.New(t)
  1297  		err = yaml.UnmarshalStrict([]byte(item.data), value.Interface())
  1298  		c.Assert(err, ErrorMatches, item.error)
  1299  	}
  1300  }
  1301  
  1302  type textUnmarshaler struct {
  1303  	S string
  1304  }
  1305  
  1306  func (t *textUnmarshaler) UnmarshalText(s []byte) error {
  1307  	t.S = string(s)
  1308  	return nil
  1309  }
  1310  
  1311  func (s *S) TestFuzzCrashers(c *C) {
  1312  	cases := []string{
  1313  		// runtime error: index out of range
  1314  		"\"\\0\\\r\n",
  1315  
  1316  		// should not happen
  1317  		"  0: [\n] 0",
  1318  		"? ? \"\n\" 0",
  1319  		"    - {\n000}0",
  1320  		"0:\n  0: [0\n] 0",
  1321  		"    - \"\n000\"0",
  1322  		"    - \"\n000\"\"",
  1323  		"0:\n    - {\n000}0",
  1324  		"0:\n    - \"\n000\"0",
  1325  		"0:\n    - \"\n000\"\"",
  1326  
  1327  		// runtime error: index out of range
  1328  		" \ufeff\n",
  1329  		"? \ufeff\n",
  1330  		"? \ufeff:\n",
  1331  		"0: \ufeff\n",
  1332  		"? \ufeff: \ufeff\n",
  1333  	}
  1334  	for _, data := range cases {
  1335  		var v interface{}
  1336  		_ = yaml.Unmarshal([]byte(data), &v)
  1337  	}
  1338  }
  1339  
  1340  //var data []byte
  1341  //func init() {
  1342  //	var err error
  1343  //	data, err = ioutil.ReadFile("/tmp/file.yaml")
  1344  //	if err != nil {
  1345  //		panic(err)
  1346  //	}
  1347  //}
  1348  //
  1349  //func (s *S) BenchmarkUnmarshal(c *C) {
  1350  //	var err error
  1351  //	for i := 0; i < c.N; i++ {
  1352  //		var v map[string]interface{}
  1353  //		err = yaml.Unmarshal(data, &v)
  1354  //	}
  1355  //	if err != nil {
  1356  //		panic(err)
  1357  //	}
  1358  //}
  1359  //
  1360  //func (s *S) BenchmarkMarshal(c *C) {
  1361  //	var v map[string]interface{}
  1362  //	yaml.Unmarshal(data, &v)
  1363  //	c.ResetTimer()
  1364  //	for i := 0; i < c.N; i++ {
  1365  //		yaml.Marshal(&v)
  1366  //	}
  1367  //}
  1368  

View as plain text