...

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

Documentation: gopkg.in/yaml.v3

     1  //
     2  // Copyright (c) 2011-2019 Canonical Ltd
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package yaml_test
    17  
    18  import (
    19  	"bytes"
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"math"
    24  	"reflect"
    25  	"strings"
    26  	"time"
    27  
    28  	. "gopkg.in/check.v1"
    29  	"gopkg.in/yaml.v3"
    30  )
    31  
    32  var unmarshalIntTest = 123
    33  
    34  var unmarshalTests = []struct {
    35  	data  string
    36  	value interface{}
    37  }{
    38  	{
    39  		"",
    40  		(*struct{})(nil),
    41  	},
    42  	{
    43  		"{}", &struct{}{},
    44  	}, {
    45  		"v: hi",
    46  		map[string]string{"v": "hi"},
    47  	}, {
    48  		"v: hi", map[string]interface{}{"v": "hi"},
    49  	}, {
    50  		"v: true",
    51  		map[string]string{"v": "true"},
    52  	}, {
    53  		"v: true",
    54  		map[string]interface{}{"v": true},
    55  	}, {
    56  		"v: 10",
    57  		map[string]interface{}{"v": 10},
    58  	}, {
    59  		"v: 0b10",
    60  		map[string]interface{}{"v": 2},
    61  	}, {
    62  		"v: 0xA",
    63  		map[string]interface{}{"v": 10},
    64  	}, {
    65  		"v: 4294967296",
    66  		map[string]int64{"v": 4294967296},
    67  	}, {
    68  		"v: 0.1",
    69  		map[string]interface{}{"v": 0.1},
    70  	}, {
    71  		"v: .1",
    72  		map[string]interface{}{"v": 0.1},
    73  	}, {
    74  		"v: .Inf",
    75  		map[string]interface{}{"v": math.Inf(+1)},
    76  	}, {
    77  		"v: -.Inf",
    78  		map[string]interface{}{"v": math.Inf(-1)},
    79  	}, {
    80  		"v: -10",
    81  		map[string]interface{}{"v": -10},
    82  	}, {
    83  		"v: -.1",
    84  		map[string]interface{}{"v": -0.1},
    85  	},
    86  
    87  	// Simple values.
    88  	{
    89  		"123",
    90  		&unmarshalIntTest,
    91  	},
    92  
    93  	// Floats from spec
    94  	{
    95  		"canonical: 6.8523e+5",
    96  		map[string]interface{}{"canonical": 6.8523e+5},
    97  	}, {
    98  		"expo: 685.230_15e+03",
    99  		map[string]interface{}{"expo": 685.23015e+03},
   100  	}, {
   101  		"fixed: 685_230.15",
   102  		map[string]interface{}{"fixed": 685230.15},
   103  	}, {
   104  		"neginf: -.inf",
   105  		map[string]interface{}{"neginf": math.Inf(-1)},
   106  	}, {
   107  		"fixed: 685_230.15",
   108  		map[string]float64{"fixed": 685230.15},
   109  	},
   110  	//{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
   111  	//{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
   112  
   113  	// Bools are per 1.2 spec.
   114  	{
   115  		"canonical: true",
   116  		map[string]interface{}{"canonical": true},
   117  	}, {
   118  		"canonical: false",
   119  		map[string]interface{}{"canonical": false},
   120  	}, {
   121  		"bool: True",
   122  		map[string]interface{}{"bool": true},
   123  	}, {
   124  		"bool: False",
   125  		map[string]interface{}{"bool": false},
   126  	}, {
   127  		"bool: TRUE",
   128  		map[string]interface{}{"bool": true},
   129  	}, {
   130  		"bool: FALSE",
   131  		map[string]interface{}{"bool": false},
   132  	},
   133  	// For backwards compatibility with 1.1, decoding old strings into typed values still works.
   134  	{
   135  		"option: on",
   136  		map[string]bool{"option": true},
   137  	}, {
   138  		"option: y",
   139  		map[string]bool{"option": true},
   140  	}, {
   141  		"option: Off",
   142  		map[string]bool{"option": false},
   143  	}, {
   144  		"option: No",
   145  		map[string]bool{"option": false},
   146  	}, {
   147  		"option: other",
   148  		map[string]bool{},
   149  	},
   150  	// Ints from spec
   151  	{
   152  		"canonical: 685230",
   153  		map[string]interface{}{"canonical": 685230},
   154  	}, {
   155  		"decimal: +685_230",
   156  		map[string]interface{}{"decimal": 685230},
   157  	}, {
   158  		"octal: 02472256",
   159  		map[string]interface{}{"octal": 685230},
   160  	}, {
   161  		"octal: -02472256",
   162  		map[string]interface{}{"octal": -685230},
   163  	}, {
   164  		"octal: 0o2472256",
   165  		map[string]interface{}{"octal": 685230},
   166  	}, {
   167  		"octal: -0o2472256",
   168  		map[string]interface{}{"octal": -685230},
   169  	}, {
   170  		"hexa: 0x_0A_74_AE",
   171  		map[string]interface{}{"hexa": 685230},
   172  	}, {
   173  		"bin: 0b1010_0111_0100_1010_1110",
   174  		map[string]interface{}{"bin": 685230},
   175  	}, {
   176  		"bin: -0b101010",
   177  		map[string]interface{}{"bin": -42},
   178  	}, {
   179  		"bin: -0b1000000000000000000000000000000000000000000000000000000000000000",
   180  		map[string]interface{}{"bin": -9223372036854775808},
   181  	}, {
   182  		"decimal: +685_230",
   183  		map[string]int{"decimal": 685230},
   184  	},
   185  
   186  	//{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
   187  
   188  	// Nulls from spec
   189  	{
   190  		"empty:",
   191  		map[string]interface{}{"empty": nil},
   192  	}, {
   193  		"canonical: ~",
   194  		map[string]interface{}{"canonical": nil},
   195  	}, {
   196  		"english: null",
   197  		map[string]interface{}{"english": nil},
   198  	}, {
   199  		"~: null key",
   200  		map[interface{}]string{nil: "null key"},
   201  	}, {
   202  		"empty:",
   203  		map[string]*bool{"empty": nil},
   204  	},
   205  
   206  	// Flow sequence
   207  	{
   208  		"seq: [A,B]",
   209  		map[string]interface{}{"seq": []interface{}{"A", "B"}},
   210  	}, {
   211  		"seq: [A,B,C,]",
   212  		map[string][]string{"seq": []string{"A", "B", "C"}},
   213  	}, {
   214  		"seq: [A,1,C]",
   215  		map[string][]string{"seq": []string{"A", "1", "C"}},
   216  	}, {
   217  		"seq: [A,1,C]",
   218  		map[string][]int{"seq": []int{1}},
   219  	}, {
   220  		"seq: [A,1,C]",
   221  		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
   222  	},
   223  	// Block sequence
   224  	{
   225  		"seq:\n - A\n - B",
   226  		map[string]interface{}{"seq": []interface{}{"A", "B"}},
   227  	}, {
   228  		"seq:\n - A\n - B\n - C",
   229  		map[string][]string{"seq": []string{"A", "B", "C"}},
   230  	}, {
   231  		"seq:\n - A\n - 1\n - C",
   232  		map[string][]string{"seq": []string{"A", "1", "C"}},
   233  	}, {
   234  		"seq:\n - A\n - 1\n - C",
   235  		map[string][]int{"seq": []int{1}},
   236  	}, {
   237  		"seq:\n - A\n - 1\n - C",
   238  		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
   239  	},
   240  
   241  	// Literal block scalar
   242  	{
   243  		"scalar: | # Comment\n\n literal\n\n \ttext\n\n",
   244  		map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
   245  	},
   246  
   247  	// Folded block scalar
   248  	{
   249  		"scalar: > # Comment\n\n folded\n line\n \n next\n line\n  * one\n  * two\n\n last\n line\n\n",
   250  		map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"},
   251  	},
   252  
   253  	// Map inside interface with no type hints.
   254  	{
   255  		"a: {b: c}",
   256  		map[interface{}]interface{}{"a": map[string]interface{}{"b": "c"}},
   257  	},
   258  	// Non-string map inside interface with no type hints.
   259  	{
   260  		"a: {b: c, 1: d}",
   261  		map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c", 1: "d"}},
   262  	},
   263  
   264  	// Structs and type conversions.
   265  	{
   266  		"hello: world",
   267  		&struct{ Hello string }{"world"},
   268  	}, {
   269  		"a: {b: c}",
   270  		&struct{ A struct{ B string } }{struct{ B string }{"c"}},
   271  	}, {
   272  		"a: {b: c}",
   273  		&struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
   274  	}, {
   275  		"a: 'null'",
   276  		&struct{ A *unmarshalerType }{&unmarshalerType{"null"}},
   277  	}, {
   278  		"a: {b: c}",
   279  		&struct{ A map[string]string }{map[string]string{"b": "c"}},
   280  	}, {
   281  		"a: {b: c}",
   282  		&struct{ A *map[string]string }{&map[string]string{"b": "c"}},
   283  	}, {
   284  		"a:",
   285  		&struct{ A map[string]string }{},
   286  	}, {
   287  		"a: 1",
   288  		&struct{ A int }{1},
   289  	}, {
   290  		"a: 1",
   291  		&struct{ A float64 }{1},
   292  	}, {
   293  		"a: 1.0",
   294  		&struct{ A int }{1},
   295  	}, {
   296  		"a: 1.0",
   297  		&struct{ A uint }{1},
   298  	}, {
   299  		"a: [1, 2]",
   300  		&struct{ A []int }{[]int{1, 2}},
   301  	}, {
   302  		"a: [1, 2]",
   303  		&struct{ A [2]int }{[2]int{1, 2}},
   304  	}, {
   305  		"a: 1",
   306  		&struct{ B int }{0},
   307  	}, {
   308  		"a: 1",
   309  		&struct {
   310  			B int "a"
   311  		}{1},
   312  	}, {
   313  		// Some limited backwards compatibility with the 1.1 spec.
   314  		"a: YES",
   315  		&struct{ A bool }{true},
   316  	},
   317  
   318  	// Some cross type conversions
   319  	{
   320  		"v: 42",
   321  		map[string]uint{"v": 42},
   322  	}, {
   323  		"v: -42",
   324  		map[string]uint{},
   325  	}, {
   326  		"v: 4294967296",
   327  		map[string]uint64{"v": 4294967296},
   328  	}, {
   329  		"v: -4294967296",
   330  		map[string]uint64{},
   331  	},
   332  
   333  	// int
   334  	{
   335  		"int_max: 2147483647",
   336  		map[string]int{"int_max": math.MaxInt32},
   337  	},
   338  	{
   339  		"int_min: -2147483648",
   340  		map[string]int{"int_min": math.MinInt32},
   341  	},
   342  	{
   343  		"int_overflow: 9223372036854775808", // math.MaxInt64 + 1
   344  		map[string]int{},
   345  	},
   346  
   347  	// int64
   348  	{
   349  		"int64_max: 9223372036854775807",
   350  		map[string]int64{"int64_max": math.MaxInt64},
   351  	},
   352  	{
   353  		"int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
   354  		map[string]int64{"int64_max_base2": math.MaxInt64},
   355  	},
   356  	{
   357  		"int64_min: -9223372036854775808",
   358  		map[string]int64{"int64_min": math.MinInt64},
   359  	},
   360  	{
   361  		"int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
   362  		map[string]int64{"int64_neg_base2": -math.MaxInt64},
   363  	},
   364  	{
   365  		"int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
   366  		map[string]int64{},
   367  	},
   368  
   369  	// uint
   370  	{
   371  		"uint_min: 0",
   372  		map[string]uint{"uint_min": 0},
   373  	},
   374  	{
   375  		"uint_max: 4294967295",
   376  		map[string]uint{"uint_max": math.MaxUint32},
   377  	},
   378  	{
   379  		"uint_underflow: -1",
   380  		map[string]uint{},
   381  	},
   382  
   383  	// uint64
   384  	{
   385  		"uint64_min: 0",
   386  		map[string]uint{"uint64_min": 0},
   387  	},
   388  	{
   389  		"uint64_max: 18446744073709551615",
   390  		map[string]uint64{"uint64_max": math.MaxUint64},
   391  	},
   392  	{
   393  		"uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
   394  		map[string]uint64{"uint64_max_base2": math.MaxUint64},
   395  	},
   396  	{
   397  		"uint64_maxint64: 9223372036854775807",
   398  		map[string]uint64{"uint64_maxint64": math.MaxInt64},
   399  	},
   400  	{
   401  		"uint64_underflow: -1",
   402  		map[string]uint64{},
   403  	},
   404  
   405  	// float32
   406  	{
   407  		"float32_max: 3.40282346638528859811704183484516925440e+38",
   408  		map[string]float32{"float32_max": math.MaxFloat32},
   409  	},
   410  	{
   411  		"float32_nonzero: 1.401298464324817070923729583289916131280e-45",
   412  		map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32},
   413  	},
   414  	{
   415  		"float32_maxuint64: 18446744073709551615",
   416  		map[string]float32{"float32_maxuint64": float32(math.MaxUint64)},
   417  	},
   418  	{
   419  		"float32_maxuint64+1: 18446744073709551616",
   420  		map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)},
   421  	},
   422  
   423  	// float64
   424  	{
   425  		"float64_max: 1.797693134862315708145274237317043567981e+308",
   426  		map[string]float64{"float64_max": math.MaxFloat64},
   427  	},
   428  	{
   429  		"float64_nonzero: 4.940656458412465441765687928682213723651e-324",
   430  		map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64},
   431  	},
   432  	{
   433  		"float64_maxuint64: 18446744073709551615",
   434  		map[string]float64{"float64_maxuint64": float64(math.MaxUint64)},
   435  	},
   436  	{
   437  		"float64_maxuint64+1: 18446744073709551616",
   438  		map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)},
   439  	},
   440  
   441  	// Overflow cases.
   442  	{
   443  		"v: 4294967297",
   444  		map[string]int32{},
   445  	}, {
   446  		"v: 128",
   447  		map[string]int8{},
   448  	},
   449  
   450  	// Quoted values.
   451  	{
   452  		"'1': '\"2\"'",
   453  		map[interface{}]interface{}{"1": "\"2\""},
   454  	}, {
   455  		"v:\n- A\n- 'B\n\n  C'\n",
   456  		map[string][]string{"v": []string{"A", "B\nC"}},
   457  	},
   458  
   459  	// Explicit tags.
   460  	{
   461  		"v: !!float '1.1'",
   462  		map[string]interface{}{"v": 1.1},
   463  	}, {
   464  		"v: !!float 0",
   465  		map[string]interface{}{"v": float64(0)},
   466  	}, {
   467  		"v: !!float -1",
   468  		map[string]interface{}{"v": float64(-1)},
   469  	}, {
   470  		"v: !!null ''",
   471  		map[string]interface{}{"v": nil},
   472  	}, {
   473  		"%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
   474  		map[string]interface{}{"v": 1},
   475  	},
   476  
   477  	// Non-specific tag (Issue #75)
   478  	{
   479  		"v: ! test",
   480  		map[string]interface{}{"v": "test"},
   481  	},
   482  
   483  	// Anchors and aliases.
   484  	{
   485  		"a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
   486  		&struct{ A, B, C, D int }{1, 2, 1, 2},
   487  	}, {
   488  		"a: &a {c: 1}\nb: *a",
   489  		&struct {
   490  			A, B struct {
   491  				C int
   492  			}
   493  		}{struct{ C int }{1}, struct{ C int }{1}},
   494  	}, {
   495  		"a: &a [1, 2]\nb: *a",
   496  		&struct{ B []int }{[]int{1, 2}},
   497  	},
   498  
   499  	// Bug #1133337
   500  	{
   501  		"foo: ''",
   502  		map[string]*string{"foo": new(string)},
   503  	}, {
   504  		"foo: null",
   505  		map[string]*string{"foo": nil},
   506  	}, {
   507  		"foo: null",
   508  		map[string]string{"foo": ""},
   509  	}, {
   510  		"foo: null",
   511  		map[string]interface{}{"foo": nil},
   512  	},
   513  
   514  	// Support for ~
   515  	{
   516  		"foo: ~",
   517  		map[string]*string{"foo": nil},
   518  	}, {
   519  		"foo: ~",
   520  		map[string]string{"foo": ""},
   521  	}, {
   522  		"foo: ~",
   523  		map[string]interface{}{"foo": nil},
   524  	},
   525  
   526  	// Ignored field
   527  	{
   528  		"a: 1\nb: 2\n",
   529  		&struct {
   530  			A int
   531  			B int "-"
   532  		}{1, 0},
   533  	},
   534  
   535  	// Bug #1191981
   536  	{
   537  		"" +
   538  			"%YAML 1.1\n" +
   539  			"--- !!str\n" +
   540  			`"Generic line break (no glyph)\n\` + "\n" +
   541  			` Generic line break (glyphed)\n\` + "\n" +
   542  			` Line separator\u2028\` + "\n" +
   543  			` Paragraph separator\u2029"` + "\n",
   544  		"" +
   545  			"Generic line break (no glyph)\n" +
   546  			"Generic line break (glyphed)\n" +
   547  			"Line separator\u2028Paragraph separator\u2029",
   548  	},
   549  
   550  	// Struct inlining
   551  	{
   552  		"a: 1\nb: 2\nc: 3\n",
   553  		&struct {
   554  			A int
   555  			C inlineB `yaml:",inline"`
   556  		}{1, inlineB{2, inlineC{3}}},
   557  	},
   558  
   559  	// Struct inlining as a pointer.
   560  	{
   561  		"a: 1\nb: 2\nc: 3\n",
   562  		&struct {
   563  			A int
   564  			C *inlineB `yaml:",inline"`
   565  		}{1, &inlineB{2, inlineC{3}}},
   566  	}, {
   567  		"a: 1\n",
   568  		&struct {
   569  			A int
   570  			C *inlineB `yaml:",inline"`
   571  		}{1, nil},
   572  	}, {
   573  		"a: 1\nc: 3\nd: 4\n",
   574  		&struct {
   575  			A int
   576  			C *inlineD `yaml:",inline"`
   577  		}{1, &inlineD{&inlineC{3}, 4}},
   578  	},
   579  
   580  	// Map inlining
   581  	{
   582  		"a: 1\nb: 2\nc: 3\n",
   583  		&struct {
   584  			A int
   585  			C map[string]int `yaml:",inline"`
   586  		}{1, map[string]int{"b": 2, "c": 3}},
   587  	},
   588  
   589  	// bug 1243827
   590  	{
   591  		"a: -b_c",
   592  		map[string]interface{}{"a": "-b_c"},
   593  	},
   594  	{
   595  		"a: +b_c",
   596  		map[string]interface{}{"a": "+b_c"},
   597  	},
   598  	{
   599  		"a: 50cent_of_dollar",
   600  		map[string]interface{}{"a": "50cent_of_dollar"},
   601  	},
   602  
   603  	// issue #295 (allow scalars with colons in flow mappings and sequences)
   604  	{
   605  		"a: {b: https://github.com/go-yaml/yaml}",
   606  		map[string]interface{}{"a": map[string]interface{}{
   607  			"b": "https://github.com/go-yaml/yaml",
   608  		}},
   609  	},
   610  	{
   611  		"a: [https://github.com/go-yaml/yaml]",
   612  		map[string]interface{}{"a": []interface{}{"https://github.com/go-yaml/yaml"}},
   613  	},
   614  
   615  	// Duration
   616  	{
   617  		"a: 3s",
   618  		map[string]time.Duration{"a": 3 * time.Second},
   619  	},
   620  
   621  	// Issue #24.
   622  	{
   623  		"a: <foo>",
   624  		map[string]string{"a": "<foo>"},
   625  	},
   626  
   627  	// Base 60 floats are obsolete and unsupported.
   628  	{
   629  		"a: 1:1\n",
   630  		map[string]string{"a": "1:1"},
   631  	},
   632  
   633  	// Binary data.
   634  	{
   635  		"a: !!binary gIGC\n",
   636  		map[string]string{"a": "\x80\x81\x82"},
   637  	}, {
   638  		"a: !!binary |\n  " + strings.Repeat("kJCQ", 17) + "kJ\n  CQ\n",
   639  		map[string]string{"a": strings.Repeat("\x90", 54)},
   640  	}, {
   641  		"a: !!binary |\n  " + strings.Repeat("A", 70) + "\n  ==\n",
   642  		map[string]string{"a": strings.Repeat("\x00", 52)},
   643  	},
   644  
   645  	// Issue #39.
   646  	{
   647  		"a:\n b:\n  c: d\n",
   648  		map[string]struct{ B interface{} }{"a": {map[string]interface{}{"c": "d"}}},
   649  	},
   650  
   651  	// Custom map type.
   652  	{
   653  		"a: {b: c}",
   654  		M{"a": M{"b": "c"}},
   655  	},
   656  
   657  	// Support encoding.TextUnmarshaler.
   658  	{
   659  		"a: 1.2.3.4\n",
   660  		map[string]textUnmarshaler{"a": textUnmarshaler{S: "1.2.3.4"}},
   661  	},
   662  	{
   663  		"a: 2015-02-24T18:19:39Z\n",
   664  		map[string]textUnmarshaler{"a": textUnmarshaler{"2015-02-24T18:19:39Z"}},
   665  	},
   666  
   667  	// Timestamps
   668  	{
   669  		// Date only.
   670  		"a: 2015-01-01\n",
   671  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   672  	},
   673  	{
   674  		// RFC3339
   675  		"a: 2015-02-24T18:19:39.12Z\n",
   676  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)},
   677  	},
   678  	{
   679  		// RFC3339 with short dates.
   680  		"a: 2015-2-3T3:4:5Z",
   681  		map[string]time.Time{"a": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)},
   682  	},
   683  	{
   684  		// ISO8601 lower case t
   685  		"a: 2015-02-24t18:19:39Z\n",
   686  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
   687  	},
   688  	{
   689  		// space separate, no time zone
   690  		"a: 2015-02-24 18:19:39\n",
   691  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
   692  	},
   693  	// Some cases not currently handled. Uncomment these when
   694  	// the code is fixed.
   695  	//	{
   696  	//		// space separated with time zone
   697  	//		"a: 2001-12-14 21:59:43.10 -5",
   698  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   699  	//	},
   700  	//	{
   701  	//		// arbitrary whitespace between fields
   702  	//		"a: 2001-12-14 \t\t \t21:59:43.10 \t Z",
   703  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   704  	//	},
   705  	{
   706  		// explicit string tag
   707  		"a: !!str 2015-01-01",
   708  		map[string]interface{}{"a": "2015-01-01"},
   709  	},
   710  	{
   711  		// explicit timestamp tag on quoted string
   712  		"a: !!timestamp \"2015-01-01\"",
   713  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   714  	},
   715  	{
   716  		// explicit timestamp tag on unquoted string
   717  		"a: !!timestamp 2015-01-01",
   718  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   719  	},
   720  	{
   721  		// quoted string that's a valid timestamp
   722  		"a: \"2015-01-01\"",
   723  		map[string]interface{}{"a": "2015-01-01"},
   724  	},
   725  	{
   726  		// explicit timestamp tag into interface.
   727  		"a: !!timestamp \"2015-01-01\"",
   728  		map[string]interface{}{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   729  	},
   730  	{
   731  		// implicit timestamp tag into interface.
   732  		"a: 2015-01-01",
   733  		map[string]interface{}{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   734  	},
   735  
   736  	// Encode empty lists as zero-length slices.
   737  	{
   738  		"a: []",
   739  		&struct{ A []int }{[]int{}},
   740  	},
   741  
   742  	// UTF-16-LE
   743  	{
   744  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
   745  		M{"ñoño": "very yes"},
   746  	},
   747  	// UTF-16-LE with surrogate.
   748  	{
   749  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
   750  		M{"ñoño": "very yes 🟔"},
   751  	},
   752  
   753  	// UTF-16-BE
   754  	{
   755  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
   756  		M{"ñoño": "very yes"},
   757  	},
   758  	// UTF-16-BE with surrogate.
   759  	{
   760  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
   761  		M{"ñoño": "very yes 🟔"},
   762  	},
   763  
   764  	// This *is* in fact a float number, per the spec. #171 was a mistake.
   765  	{
   766  		"a: 123456e1\n",
   767  		M{"a": 123456e1},
   768  	}, {
   769  		"a: 123456E1\n",
   770  		M{"a": 123456e1},
   771  	},
   772  	// yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes
   773  	{
   774  		"First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n",
   775  		map[string]interface{}{
   776  			"First occurrence":  "Foo",
   777  			"Second occurrence": "Foo",
   778  			"Override anchor":   "Bar",
   779  			"Reuse anchor":      "Bar",
   780  		},
   781  	},
   782  	// Single document with garbage following it.
   783  	{
   784  		"---\nhello\n...\n}not yaml",
   785  		"hello",
   786  	},
   787  
   788  	// Comment scan exhausting the input buffer (issue #469).
   789  	{
   790  		"true\n#" + strings.Repeat(" ", 512*3),
   791  		"true",
   792  	}, {
   793  		"true #" + strings.Repeat(" ", 512*3),
   794  		"true",
   795  	},
   796  
   797  	// CRLF
   798  	{
   799  		"a: b\r\nc:\r\n- d\r\n- e\r\n",
   800  		map[string]interface{}{
   801  			"a": "b",
   802  			"c": []interface{}{"d", "e"},
   803  		},
   804  	},
   805  }
   806  
   807  type M map[string]interface{}
   808  
   809  type inlineB struct {
   810  	B       int
   811  	inlineC `yaml:",inline"`
   812  }
   813  
   814  type inlineC struct {
   815  	C int
   816  }
   817  
   818  type inlineD struct {
   819  	C *inlineC `yaml:",inline"`
   820  	D int
   821  }
   822  
   823  func (s *S) TestUnmarshal(c *C) {
   824  	for i, item := range unmarshalTests {
   825  		c.Logf("test %d: %q", i, item.data)
   826  		t := reflect.ValueOf(item.value).Type()
   827  		value := reflect.New(t)
   828  		err := yaml.Unmarshal([]byte(item.data), value.Interface())
   829  		if _, ok := err.(*yaml.TypeError); !ok {
   830  			c.Assert(err, IsNil)
   831  		}
   832  		c.Assert(value.Elem().Interface(), DeepEquals, item.value, Commentf("error: %v", err))
   833  	}
   834  }
   835  
   836  func (s *S) TestUnmarshalFullTimestamp(c *C) {
   837  	// Full timestamp in same format as encoded. This is confirmed to be
   838  	// properly decoded by Python as a timestamp as well.
   839  	var str = "2015-02-24T18:19:39.123456789-03:00"
   840  	var t interface{}
   841  	err := yaml.Unmarshal([]byte(str), &t)
   842  	c.Assert(err, IsNil)
   843  	c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.(time.Time).Location()))
   844  	c.Assert(t.(time.Time).In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC))
   845  }
   846  
   847  func (s *S) TestDecoderSingleDocument(c *C) {
   848  	// Test that Decoder.Decode works as expected on
   849  	// all the unmarshal tests.
   850  	for i, item := range unmarshalTests {
   851  		c.Logf("test %d: %q", i, item.data)
   852  		if item.data == "" {
   853  			// Behaviour differs when there's no YAML.
   854  			continue
   855  		}
   856  		t := reflect.ValueOf(item.value).Type()
   857  		value := reflect.New(t)
   858  		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(value.Interface())
   859  		if _, ok := err.(*yaml.TypeError); !ok {
   860  			c.Assert(err, IsNil)
   861  		}
   862  		c.Assert(value.Elem().Interface(), DeepEquals, item.value)
   863  	}
   864  }
   865  
   866  var decoderTests = []struct {
   867  	data   string
   868  	values []interface{}
   869  }{{
   870  	"",
   871  	nil,
   872  }, {
   873  	"a: b",
   874  	[]interface{}{
   875  		map[string]interface{}{"a": "b"},
   876  	},
   877  }, {
   878  	"---\na: b\n...\n",
   879  	[]interface{}{
   880  		map[string]interface{}{"a": "b"},
   881  	},
   882  }, {
   883  	"---\n'hello'\n...\n---\ngoodbye\n...\n",
   884  	[]interface{}{
   885  		"hello",
   886  		"goodbye",
   887  	},
   888  }}
   889  
   890  func (s *S) TestDecoder(c *C) {
   891  	for i, item := range decoderTests {
   892  		c.Logf("test %d: %q", i, item.data)
   893  		var values []interface{}
   894  		dec := yaml.NewDecoder(strings.NewReader(item.data))
   895  		for {
   896  			var value interface{}
   897  			err := dec.Decode(&value)
   898  			if err == io.EOF {
   899  				break
   900  			}
   901  			c.Assert(err, IsNil)
   902  			values = append(values, value)
   903  		}
   904  		c.Assert(values, DeepEquals, item.values)
   905  	}
   906  }
   907  
   908  type errReader struct{}
   909  
   910  func (errReader) Read([]byte) (int, error) {
   911  	return 0, errors.New("some read error")
   912  }
   913  
   914  func (s *S) TestDecoderReadError(c *C) {
   915  	err := yaml.NewDecoder(errReader{}).Decode(&struct{}{})
   916  	c.Assert(err, ErrorMatches, `yaml: input error: some read error`)
   917  }
   918  
   919  func (s *S) TestUnmarshalNaN(c *C) {
   920  	value := map[string]interface{}{}
   921  	err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
   922  	c.Assert(err, IsNil)
   923  	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
   924  }
   925  
   926  func (s *S) TestUnmarshalDurationInt(c *C) {
   927  	// Don't accept plain ints as durations as it's unclear (issue #200).
   928  	var d time.Duration
   929  	err := yaml.Unmarshal([]byte("123"), &d)
   930  	c.Assert(err, ErrorMatches, "(?s).* line 1: cannot unmarshal !!int `123` into time.Duration")
   931  }
   932  
   933  var unmarshalErrorTests = []struct {
   934  	data, error string
   935  }{
   936  	{"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
   937  	{"v: [A,", "yaml: line 1: did not find expected node content"},
   938  	{"v:\n- [A,", "yaml: line 2: did not find expected node content"},
   939  	{"a:\n- b: *,", "yaml: line 2: did not find expected alphabetic or numeric character"},
   940  	{"a: *b\n", "yaml: unknown anchor 'b' referenced"},
   941  	{"a: &a\n  b: *a\n", "yaml: anchor 'a' value contains itself"},
   942  	{"value: -", "yaml: block sequence entries are not allowed in this context"},
   943  	{"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
   944  	{"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
   945  	{"{{.}}", `yaml: invalid map key: map\[string]interface \{\}\{".":interface \{\}\(nil\)\}`},
   946  	{"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
   947  	{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
   948  	{"a:\n  1:\nb\n  2:", ".*could not find expected ':'"},
   949  	{"a: 1\nb: 2\nc 2\nd: 3\n", "^yaml: line 3: could not find expected ':'$"},
   950  	{"#\n-\n{", "yaml: line 3: could not find expected ':'"}, // Issue #665
   951  	{"0: [:!00 \xef", "yaml: incomplete UTF-8 octet sequence"}, // Issue #666
   952  	{
   953  		"a: &a [00,00,00,00,00,00,00,00,00]\n" +
   954  			"b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" +
   955  			"c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]\n" +
   956  			"d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]\n" +
   957  			"e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]\n" +
   958  			"f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]\n" +
   959  			"g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]\n" +
   960  			"h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]\n" +
   961  			"i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]\n",
   962  		"yaml: document contains excessive aliasing",
   963  	},
   964  }
   965  
   966  func (s *S) TestUnmarshalErrors(c *C) {
   967  	for i, item := range unmarshalErrorTests {
   968  		c.Logf("test %d: %q", i, item.data)
   969  		var value interface{}
   970  		err := yaml.Unmarshal([]byte(item.data), &value)
   971  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   972  	}
   973  }
   974  
   975  func (s *S) TestDecoderErrors(c *C) {
   976  	for _, item := range unmarshalErrorTests {
   977  		var value interface{}
   978  		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(&value)
   979  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   980  	}
   981  }
   982  
   983  var unmarshalerTests = []struct {
   984  	data, tag string
   985  	value     interface{}
   986  }{
   987  	{"_: {hi: there}", "!!map", map[string]interface{}{"hi": "there"}},
   988  	{"_: [1,A]", "!!seq", []interface{}{1, "A"}},
   989  	{"_: 10", "!!int", 10},
   990  	{"_: null", "!!null", nil},
   991  	{`_: BAR!`, "!!str", "BAR!"},
   992  	{`_: "BAR!"`, "!!str", "BAR!"},
   993  	{"_: !!foo 'BAR!'", "!!foo", "BAR!"},
   994  	{`_: ""`, "!!str", ""},
   995  }
   996  
   997  var unmarshalerResult = map[int]error{}
   998  
   999  type unmarshalerType struct {
  1000  	value interface{}
  1001  }
  1002  
  1003  func (o *unmarshalerType) UnmarshalYAML(value *yaml.Node) error {
  1004  	if err := value.Decode(&o.value); err != nil {
  1005  		return err
  1006  	}
  1007  	if i, ok := o.value.(int); ok {
  1008  		if result, ok := unmarshalerResult[i]; ok {
  1009  			return result
  1010  		}
  1011  	}
  1012  	return nil
  1013  }
  1014  
  1015  type unmarshalerPointer struct {
  1016  	Field *unmarshalerType "_"
  1017  }
  1018  
  1019  type unmarshalerValue struct {
  1020  	Field unmarshalerType "_"
  1021  }
  1022  
  1023  type unmarshalerInlined struct {
  1024  	Field   *unmarshalerType "_"
  1025  	Inlined unmarshalerType  `yaml:",inline"`
  1026  }
  1027  
  1028  type unmarshalerInlinedTwice struct {
  1029  	InlinedTwice unmarshalerInlined `yaml:",inline"`
  1030  }
  1031  
  1032  type obsoleteUnmarshalerType struct {
  1033  	value interface{}
  1034  }
  1035  
  1036  func (o *obsoleteUnmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
  1037  	if err := unmarshal(&o.value); err != nil {
  1038  		return err
  1039  	}
  1040  	if i, ok := o.value.(int); ok {
  1041  		if result, ok := unmarshalerResult[i]; ok {
  1042  			return result
  1043  		}
  1044  	}
  1045  	return nil
  1046  }
  1047  
  1048  type obsoleteUnmarshalerPointer struct {
  1049  	Field *obsoleteUnmarshalerType "_"
  1050  }
  1051  
  1052  type obsoleteUnmarshalerValue struct {
  1053  	Field obsoleteUnmarshalerType "_"
  1054  }
  1055  
  1056  func (s *S) TestUnmarshalerPointerField(c *C) {
  1057  	for _, item := range unmarshalerTests {
  1058  		obj := &unmarshalerPointer{}
  1059  		err := yaml.Unmarshal([]byte(item.data), obj)
  1060  		c.Assert(err, IsNil)
  1061  		if item.value == nil {
  1062  			c.Assert(obj.Field, IsNil)
  1063  		} else {
  1064  			c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  1065  			c.Assert(obj.Field.value, DeepEquals, item.value)
  1066  		}
  1067  	}
  1068  	for _, item := range unmarshalerTests {
  1069  		obj := &obsoleteUnmarshalerPointer{}
  1070  		err := yaml.Unmarshal([]byte(item.data), obj)
  1071  		c.Assert(err, IsNil)
  1072  		if item.value == nil {
  1073  			c.Assert(obj.Field, IsNil)
  1074  		} else {
  1075  			c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  1076  			c.Assert(obj.Field.value, DeepEquals, item.value)
  1077  		}
  1078  	}
  1079  }
  1080  
  1081  func (s *S) TestUnmarshalerValueField(c *C) {
  1082  	for _, item := range unmarshalerTests {
  1083  		obj := &obsoleteUnmarshalerValue{}
  1084  		err := yaml.Unmarshal([]byte(item.data), obj)
  1085  		c.Assert(err, IsNil)
  1086  		c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  1087  		c.Assert(obj.Field.value, DeepEquals, item.value)
  1088  	}
  1089  }
  1090  
  1091  func (s *S) TestUnmarshalerInlinedField(c *C) {
  1092  	obj := &unmarshalerInlined{}
  1093  	err := yaml.Unmarshal([]byte("_: a\ninlined: b\n"), obj)
  1094  	c.Assert(err, IsNil)
  1095  	c.Assert(obj.Field, DeepEquals, &unmarshalerType{"a"})
  1096  	c.Assert(obj.Inlined, DeepEquals, unmarshalerType{map[string]interface{}{"_": "a", "inlined": "b"}})
  1097  
  1098  	twc := &unmarshalerInlinedTwice{}
  1099  	err = yaml.Unmarshal([]byte("_: a\ninlined: b\n"), twc)
  1100  	c.Assert(err, IsNil)
  1101  	c.Assert(twc.InlinedTwice.Field, DeepEquals, &unmarshalerType{"a"})
  1102  	c.Assert(twc.InlinedTwice.Inlined, DeepEquals, unmarshalerType{map[string]interface{}{"_": "a", "inlined": "b"}})
  1103  }
  1104  
  1105  func (s *S) TestUnmarshalerWholeDocument(c *C) {
  1106  	obj := &obsoleteUnmarshalerType{}
  1107  	err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
  1108  	c.Assert(err, IsNil)
  1109  	value, ok := obj.value.(map[string]interface{})
  1110  	c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
  1111  	c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
  1112  }
  1113  
  1114  func (s *S) TestUnmarshalerTypeError(c *C) {
  1115  	unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
  1116  	unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
  1117  	defer func() {
  1118  		delete(unmarshalerResult, 2)
  1119  		delete(unmarshalerResult, 4)
  1120  	}()
  1121  
  1122  	type T struct {
  1123  		Before int
  1124  		After  int
  1125  		M      map[string]*unmarshalerType
  1126  	}
  1127  	var v T
  1128  	data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
  1129  	err := yaml.Unmarshal([]byte(data), &v)
  1130  	c.Assert(err, ErrorMatches, ""+
  1131  		"yaml: unmarshal errors:\n"+
  1132  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1133  		"  foo\n"+
  1134  		"  bar\n"+
  1135  		"  line 1: cannot unmarshal !!str `B` into int")
  1136  	c.Assert(v.M["abc"], NotNil)
  1137  	c.Assert(v.M["def"], IsNil)
  1138  	c.Assert(v.M["ghi"], NotNil)
  1139  	c.Assert(v.M["jkl"], IsNil)
  1140  
  1141  	c.Assert(v.M["abc"].value, Equals, 1)
  1142  	c.Assert(v.M["ghi"].value, Equals, 3)
  1143  }
  1144  
  1145  func (s *S) TestObsoleteUnmarshalerTypeError(c *C) {
  1146  	unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
  1147  	unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
  1148  	defer func() {
  1149  		delete(unmarshalerResult, 2)
  1150  		delete(unmarshalerResult, 4)
  1151  	}()
  1152  
  1153  	type T struct {
  1154  		Before int
  1155  		After  int
  1156  		M      map[string]*obsoleteUnmarshalerType
  1157  	}
  1158  	var v T
  1159  	data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
  1160  	err := yaml.Unmarshal([]byte(data), &v)
  1161  	c.Assert(err, ErrorMatches, ""+
  1162  		"yaml: unmarshal errors:\n"+
  1163  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1164  		"  foo\n"+
  1165  		"  bar\n"+
  1166  		"  line 1: cannot unmarshal !!str `B` into int")
  1167  	c.Assert(v.M["abc"], NotNil)
  1168  	c.Assert(v.M["def"], IsNil)
  1169  	c.Assert(v.M["ghi"], NotNil)
  1170  	c.Assert(v.M["jkl"], IsNil)
  1171  
  1172  	c.Assert(v.M["abc"].value, Equals, 1)
  1173  	c.Assert(v.M["ghi"].value, Equals, 3)
  1174  }
  1175  
  1176  type proxyTypeError struct{}
  1177  
  1178  func (v *proxyTypeError) UnmarshalYAML(node *yaml.Node) error {
  1179  	var s string
  1180  	var a int32
  1181  	var b int64
  1182  	if err := node.Decode(&s); err != nil {
  1183  		panic(err)
  1184  	}
  1185  	if s == "a" {
  1186  		if err := node.Decode(&b); err == nil {
  1187  			panic("should have failed")
  1188  		}
  1189  		return node.Decode(&a)
  1190  	}
  1191  	if err := node.Decode(&a); err == nil {
  1192  		panic("should have failed")
  1193  	}
  1194  	return node.Decode(&b)
  1195  }
  1196  
  1197  func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
  1198  	type T struct {
  1199  		Before int
  1200  		After  int
  1201  		M      map[string]*proxyTypeError
  1202  	}
  1203  	var v T
  1204  	data := `{before: A, m: {abc: a, def: b}, after: B}`
  1205  	err := yaml.Unmarshal([]byte(data), &v)
  1206  	c.Assert(err, ErrorMatches, ""+
  1207  		"yaml: unmarshal errors:\n"+
  1208  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1209  		"  line 1: cannot unmarshal !!str `a` into int32\n"+
  1210  		"  line 1: cannot unmarshal !!str `b` into int64\n"+
  1211  		"  line 1: cannot unmarshal !!str `B` into int")
  1212  }
  1213  
  1214  type obsoleteProxyTypeError struct{}
  1215  
  1216  func (v *obsoleteProxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1217  	var s string
  1218  	var a int32
  1219  	var b int64
  1220  	if err := unmarshal(&s); err != nil {
  1221  		panic(err)
  1222  	}
  1223  	if s == "a" {
  1224  		if err := unmarshal(&b); err == nil {
  1225  			panic("should have failed")
  1226  		}
  1227  		return unmarshal(&a)
  1228  	}
  1229  	if err := unmarshal(&a); err == nil {
  1230  		panic("should have failed")
  1231  	}
  1232  	return unmarshal(&b)
  1233  }
  1234  
  1235  func (s *S) TestObsoleteUnmarshalerTypeErrorProxying(c *C) {
  1236  	type T struct {
  1237  		Before int
  1238  		After  int
  1239  		M      map[string]*obsoleteProxyTypeError
  1240  	}
  1241  	var v T
  1242  	data := `{before: A, m: {abc: a, def: b}, after: B}`
  1243  	err := yaml.Unmarshal([]byte(data), &v)
  1244  	c.Assert(err, ErrorMatches, ""+
  1245  		"yaml: unmarshal errors:\n"+
  1246  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1247  		"  line 1: cannot unmarshal !!str `a` into int32\n"+
  1248  		"  line 1: cannot unmarshal !!str `b` into int64\n"+
  1249  		"  line 1: cannot unmarshal !!str `B` into int")
  1250  }
  1251  
  1252  var failingErr = errors.New("failingErr")
  1253  
  1254  type failingUnmarshaler struct{}
  1255  
  1256  func (ft *failingUnmarshaler) UnmarshalYAML(node *yaml.Node) error {
  1257  	return failingErr
  1258  }
  1259  
  1260  func (s *S) TestUnmarshalerError(c *C) {
  1261  	err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
  1262  	c.Assert(err, Equals, failingErr)
  1263  }
  1264  
  1265  type obsoleteFailingUnmarshaler struct{}
  1266  
  1267  func (ft *obsoleteFailingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1268  	return failingErr
  1269  }
  1270  
  1271  func (s *S) TestObsoleteUnmarshalerError(c *C) {
  1272  	err := yaml.Unmarshal([]byte("a: b"), &obsoleteFailingUnmarshaler{})
  1273  	c.Assert(err, Equals, failingErr)
  1274  }
  1275  
  1276  type sliceUnmarshaler []int
  1277  
  1278  func (su *sliceUnmarshaler) UnmarshalYAML(node *yaml.Node) error {
  1279  	var slice []int
  1280  	err := node.Decode(&slice)
  1281  	if err == nil {
  1282  		*su = slice
  1283  		return nil
  1284  	}
  1285  
  1286  	var intVal int
  1287  	err = node.Decode(&intVal)
  1288  	if err == nil {
  1289  		*su = []int{intVal}
  1290  		return nil
  1291  	}
  1292  
  1293  	return err
  1294  }
  1295  
  1296  func (s *S) TestUnmarshalerRetry(c *C) {
  1297  	var su sliceUnmarshaler
  1298  	err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
  1299  	c.Assert(err, IsNil)
  1300  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
  1301  
  1302  	err = yaml.Unmarshal([]byte("1"), &su)
  1303  	c.Assert(err, IsNil)
  1304  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
  1305  }
  1306  
  1307  type obsoleteSliceUnmarshaler []int
  1308  
  1309  func (su *obsoleteSliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1310  	var slice []int
  1311  	err := unmarshal(&slice)
  1312  	if err == nil {
  1313  		*su = slice
  1314  		return nil
  1315  	}
  1316  
  1317  	var intVal int
  1318  	err = unmarshal(&intVal)
  1319  	if err == nil {
  1320  		*su = []int{intVal}
  1321  		return nil
  1322  	}
  1323  
  1324  	return err
  1325  }
  1326  
  1327  func (s *S) TestObsoleteUnmarshalerRetry(c *C) {
  1328  	var su obsoleteSliceUnmarshaler
  1329  	err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
  1330  	c.Assert(err, IsNil)
  1331  	c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1, 2, 3}))
  1332  
  1333  	err = yaml.Unmarshal([]byte("1"), &su)
  1334  	c.Assert(err, IsNil)
  1335  	c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1}))
  1336  }
  1337  
  1338  // From http://yaml.org/type/merge.html
  1339  var mergeTests = `
  1340  anchors:
  1341    list:
  1342      - &CENTER { "x": 1, "y": 2 }
  1343      - &LEFT   { "x": 0, "y": 2 }
  1344      - &BIG    { "r": 10 }
  1345      - &SMALL  { "r": 1 }
  1346  
  1347  # All the following maps are equal:
  1348  
  1349  plain:
  1350    # Explicit keys
  1351    "x": 1
  1352    "y": 2
  1353    "r": 10
  1354    label: center/big
  1355  
  1356  mergeOne:
  1357    # Merge one map
  1358    << : *CENTER
  1359    "r": 10
  1360    label: center/big
  1361  
  1362  mergeMultiple:
  1363    # Merge multiple maps
  1364    << : [ *CENTER, *BIG ]
  1365    label: center/big
  1366  
  1367  override:
  1368    # Override
  1369    << : [ *BIG, *LEFT, *SMALL ]
  1370    "x": 1
  1371    label: center/big
  1372  
  1373  shortTag:
  1374    # Explicit short merge tag
  1375    !!merge "<<" : [ *CENTER, *BIG ]
  1376    label: center/big
  1377  
  1378  longTag:
  1379    # Explicit merge long tag
  1380    !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
  1381    label: center/big
  1382  
  1383  inlineMap:
  1384    # Inlined map 
  1385    << : {"x": 1, "y": 2, "r": 10}
  1386    label: center/big
  1387  
  1388  inlineSequenceMap:
  1389    # Inlined map in sequence
  1390    << : [ *CENTER, {"r": 10} ]
  1391    label: center/big
  1392  `
  1393  
  1394  func (s *S) TestMerge(c *C) {
  1395  	var want = map[string]interface{}{
  1396  		"x":     1,
  1397  		"y":     2,
  1398  		"r":     10,
  1399  		"label": "center/big",
  1400  	}
  1401  
  1402  	wantStringMap := make(map[string]interface{})
  1403  	for k, v := range want {
  1404  		wantStringMap[fmt.Sprintf("%v", k)] = v
  1405  	}
  1406  
  1407  	var m map[interface{}]interface{}
  1408  	err := yaml.Unmarshal([]byte(mergeTests), &m)
  1409  	c.Assert(err, IsNil)
  1410  	for name, test := range m {
  1411  		if name == "anchors" {
  1412  			continue
  1413  		}
  1414  		if name == "plain" {
  1415  			c.Assert(test, DeepEquals, wantStringMap, Commentf("test %q failed", name))
  1416  			continue
  1417  		}
  1418  		c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
  1419  	}
  1420  }
  1421  
  1422  func (s *S) TestMergeStruct(c *C) {
  1423  	type Data struct {
  1424  		X, Y, R int
  1425  		Label   string
  1426  	}
  1427  	want := Data{1, 2, 10, "center/big"}
  1428  
  1429  	var m map[string]Data
  1430  	err := yaml.Unmarshal([]byte(mergeTests), &m)
  1431  	c.Assert(err, IsNil)
  1432  	for name, test := range m {
  1433  		if name == "anchors" {
  1434  			continue
  1435  		}
  1436  		c.Assert(test, Equals, want, Commentf("test %q failed", name))
  1437  	}
  1438  }
  1439  
  1440  var mergeTestsNested = `
  1441  mergeouter1: &mergeouter1
  1442      d: 40
  1443      e: 50
  1444  
  1445  mergeouter2: &mergeouter2
  1446      e: 5
  1447      f: 6
  1448      g: 70
  1449  
  1450  mergeinner1: &mergeinner1
  1451      <<: *mergeouter1
  1452      inner:
  1453          a: 1
  1454          b: 2
  1455  
  1456  mergeinner2: &mergeinner2
  1457      <<: *mergeouter2
  1458      inner:
  1459          a: -1
  1460          b: -2
  1461  
  1462  outer:
  1463      <<: [*mergeinner1, *mergeinner2]
  1464      f: 60
  1465      inner:
  1466          a: 10
  1467  `
  1468  
  1469  func (s *S) TestMergeNestedStruct(c *C) {
  1470  	// Issue #818: Merging used to just unmarshal twice on the target
  1471  	// value, which worked for maps as these were replaced by the new map,
  1472  	// but not on struct values as these are preserved. This resulted in
  1473  	// the nested data from the merged map to be mixed up with the data
  1474  	// from the map being merged into.
  1475  	//
  1476  	// This test also prevents two potential bugs from showing up:
  1477  	//
  1478  	// 1) A simple implementation might just zero out the nested value
  1479  	//    before unmarshaling the second time, but this would clobber previous
  1480  	//    data that is usually respected ({C: 30} below).
  1481  	//
  1482  	// 2) A simple implementation might attempt to handle the key skipping
  1483  	//    directly by iterating over the merging map without recursion, but
  1484  	//    there are more complex cases that require recursion.
  1485  	// 
  1486  	// Quick summary of the fields:
  1487  	//
  1488  	// - A must come from outer and not overriden
  1489  	// - B must not be set as its in the ignored merge
  1490  	// - C should still be set as it's preset in the value
  1491  	// - D should be set from the recursive merge
  1492  	// - E should be set from the first recursive merge, ignored on the second
  1493  	// - F should be set in the inlined map from outer, ignored later
  1494  	// - G should be set in the inlined map from the second recursive merge
  1495  	//
  1496  
  1497  	type Inner struct {
  1498  		A, B, C int
  1499  	}
  1500  	type Outer struct {
  1501  		D, E      int
  1502  		Inner  Inner
  1503  		Inline map[string]int `yaml:",inline"`
  1504  	}
  1505  	type Data struct {
  1506  		Outer Outer
  1507  	}
  1508  
  1509  	test := Data{Outer{0, 0, Inner{C: 30}, nil}}
  1510  	want := Data{Outer{40, 50, Inner{A: 10, C: 30}, map[string]int{"f": 60, "g": 70}}}
  1511  
  1512  	err := yaml.Unmarshal([]byte(mergeTestsNested), &test)
  1513  	c.Assert(err, IsNil)
  1514  	c.Assert(test, DeepEquals, want)
  1515  
  1516  	// Repeat test with a map.
  1517  
  1518  	var testm map[string]interface{}
  1519  	var wantm = map[string]interface {} {
  1520  		"f":     60,
  1521  		"inner": map[string]interface{}{
  1522  		    "a": 10,
  1523  		},
  1524  		"d": 40,
  1525  		"e": 50,
  1526  		"g": 70,
  1527  	}
  1528  	err = yaml.Unmarshal([]byte(mergeTestsNested), &testm)
  1529  	c.Assert(err, IsNil)
  1530  	c.Assert(testm["outer"], DeepEquals, wantm)
  1531  }
  1532  
  1533  var unmarshalNullTests = []struct {
  1534  	input              string
  1535  	pristine, expected func() interface{}
  1536  }{{
  1537  	"null",
  1538  	func() interface{} { var v interface{}; v = "v"; return &v },
  1539  	func() interface{} { var v interface{}; v = nil; return &v },
  1540  }, {
  1541  	"null",
  1542  	func() interface{} { var s = "s"; return &s },
  1543  	func() interface{} { var s = "s"; return &s },
  1544  }, {
  1545  	"null",
  1546  	func() interface{} { var s = "s"; sptr := &s; return &sptr },
  1547  	func() interface{} { var sptr *string; return &sptr },
  1548  }, {
  1549  	"null",
  1550  	func() interface{} { var i = 1; return &i },
  1551  	func() interface{} { var i = 1; return &i },
  1552  }, {
  1553  	"null",
  1554  	func() interface{} { var i = 1; iptr := &i; return &iptr },
  1555  	func() interface{} { var iptr *int; return &iptr },
  1556  }, {
  1557  	"null",
  1558  	func() interface{} { var m = map[string]int{"s": 1}; return &m },
  1559  	func() interface{} { var m map[string]int; return &m },
  1560  }, {
  1561  	"null",
  1562  	func() interface{} { var m = map[string]int{"s": 1}; return m },
  1563  	func() interface{} { var m = map[string]int{"s": 1}; return m },
  1564  }, {
  1565  	"s2: null\ns3: null",
  1566  	func() interface{} { var m = map[string]int{"s1": 1, "s2": 2}; return m },
  1567  	func() interface{} { var m = map[string]int{"s1": 1, "s2": 2, "s3": 0}; return m },
  1568  }, {
  1569  	"s2: null\ns3: null",
  1570  	func() interface{} { var m = map[string]interface{}{"s1": 1, "s2": 2}; return m },
  1571  	func() interface{} { var m = map[string]interface{}{"s1": 1, "s2": nil, "s3": nil}; return m },
  1572  }}
  1573  
  1574  func (s *S) TestUnmarshalNull(c *C) {
  1575  	for _, test := range unmarshalNullTests {
  1576  		pristine := test.pristine()
  1577  		expected := test.expected()
  1578  		err := yaml.Unmarshal([]byte(test.input), pristine)
  1579  		c.Assert(err, IsNil)
  1580  		c.Assert(pristine, DeepEquals, expected)
  1581  	}
  1582  }
  1583  
  1584  func (s *S) TestUnmarshalPreservesData(c *C) {
  1585  	var v struct {
  1586  		A, B int
  1587  		C    int `yaml:"-"`
  1588  	}
  1589  	v.A = 42
  1590  	v.C = 88
  1591  	err := yaml.Unmarshal([]byte("---"), &v)
  1592  	c.Assert(err, IsNil)
  1593  	c.Assert(v.A, Equals, 42)
  1594  	c.Assert(v.B, Equals, 0)
  1595  	c.Assert(v.C, Equals, 88)
  1596  
  1597  	err = yaml.Unmarshal([]byte("b: 21\nc: 99"), &v)
  1598  	c.Assert(err, IsNil)
  1599  	c.Assert(v.A, Equals, 42)
  1600  	c.Assert(v.B, Equals, 21)
  1601  	c.Assert(v.C, Equals, 88)
  1602  }
  1603  
  1604  func (s *S) TestUnmarshalSliceOnPreset(c *C) {
  1605  	// Issue #48.
  1606  	v := struct{ A []int }{[]int{1}}
  1607  	yaml.Unmarshal([]byte("a: [2]"), &v)
  1608  	c.Assert(v.A, DeepEquals, []int{2})
  1609  }
  1610  
  1611  var unmarshalStrictTests = []struct {
  1612  	known  bool
  1613  	unique bool
  1614  	data   string
  1615  	value  interface{}
  1616  	error  string
  1617  }{{
  1618  	known: true,
  1619  	data:  "a: 1\nc: 2\n",
  1620  	value: struct{ A, B int }{A: 1},
  1621  	error: `yaml: unmarshal errors:\n  line 2: field c not found in type struct { A int; B int }`,
  1622  }, {
  1623  	unique: true,
  1624  	data:   "a: 1\nb: 2\na: 3\n",
  1625  	value:  struct{ A, B int }{A: 3, B: 2},
  1626  	error:  `yaml: unmarshal errors:\n  line 3: mapping key "a" already defined at line 1`,
  1627  }, {
  1628  	unique: true,
  1629  	data:   "c: 3\na: 1\nb: 2\nc: 4\n",
  1630  	value: struct {
  1631  		A       int
  1632  		inlineB `yaml:",inline"`
  1633  	}{
  1634  		A: 1,
  1635  		inlineB: inlineB{
  1636  			B: 2,
  1637  			inlineC: inlineC{
  1638  				C: 4,
  1639  			},
  1640  		},
  1641  	},
  1642  	error: `yaml: unmarshal errors:\n  line 4: mapping key "c" already defined at line 1`,
  1643  }, {
  1644  	unique: true,
  1645  	data:   "c: 0\na: 1\nb: 2\nc: 1\n",
  1646  	value: struct {
  1647  		A       int
  1648  		inlineB `yaml:",inline"`
  1649  	}{
  1650  		A: 1,
  1651  		inlineB: inlineB{
  1652  			B: 2,
  1653  			inlineC: inlineC{
  1654  				C: 1,
  1655  			},
  1656  		},
  1657  	},
  1658  	error: `yaml: unmarshal errors:\n  line 4: mapping key "c" already defined at line 1`,
  1659  }, {
  1660  	unique: true,
  1661  	data:   "c: 1\na: 1\nb: 2\nc: 3\n",
  1662  	value: struct {
  1663  		A int
  1664  		M map[string]interface{} `yaml:",inline"`
  1665  	}{
  1666  		A: 1,
  1667  		M: map[string]interface{}{
  1668  			"b": 2,
  1669  			"c": 3,
  1670  		},
  1671  	},
  1672  	error: `yaml: unmarshal errors:\n  line 4: mapping key "c" already defined at line 1`,
  1673  }, {
  1674  	unique: true,
  1675  	data:   "a: 1\n9: 2\nnull: 3\n9: 4",
  1676  	value: map[interface{}]interface{}{
  1677  		"a": 1,
  1678  		nil: 3,
  1679  		9:   4,
  1680  	},
  1681  	error: `yaml: unmarshal errors:\n  line 4: mapping key "9" already defined at line 2`,
  1682  }}
  1683  
  1684  func (s *S) TestUnmarshalKnownFields(c *C) {
  1685  	for i, item := range unmarshalStrictTests {
  1686  		c.Logf("test %d: %q", i, item.data)
  1687  		// First test that normal Unmarshal unmarshals to the expected value.
  1688  		if !item.unique {
  1689  			t := reflect.ValueOf(item.value).Type()
  1690  			value := reflect.New(t)
  1691  			err := yaml.Unmarshal([]byte(item.data), value.Interface())
  1692  			c.Assert(err, Equals, nil)
  1693  			c.Assert(value.Elem().Interface(), DeepEquals, item.value)
  1694  		}
  1695  
  1696  		// Then test that it fails on the same thing with KnownFields on.
  1697  		t := reflect.ValueOf(item.value).Type()
  1698  		value := reflect.New(t)
  1699  		dec := yaml.NewDecoder(bytes.NewBuffer([]byte(item.data)))
  1700  		dec.KnownFields(item.known)
  1701  		err := dec.Decode(value.Interface())
  1702  		c.Assert(err, ErrorMatches, item.error)
  1703  	}
  1704  }
  1705  
  1706  type textUnmarshaler struct {
  1707  	S string
  1708  }
  1709  
  1710  func (t *textUnmarshaler) UnmarshalText(s []byte) error {
  1711  	t.S = string(s)
  1712  	return nil
  1713  }
  1714  
  1715  func (s *S) TestFuzzCrashers(c *C) {
  1716  	cases := []string{
  1717  		// runtime error: index out of range
  1718  		"\"\\0\\\r\n",
  1719  
  1720  		// should not happen
  1721  		"  0: [\n] 0",
  1722  		"? ? \"\n\" 0",
  1723  		"    - {\n000}0",
  1724  		"0:\n  0: [0\n] 0",
  1725  		"    - \"\n000\"0",
  1726  		"    - \"\n000\"\"",
  1727  		"0:\n    - {\n000}0",
  1728  		"0:\n    - \"\n000\"0",
  1729  		"0:\n    - \"\n000\"\"",
  1730  
  1731  		// runtime error: index out of range
  1732  		" \ufeff\n",
  1733  		"? \ufeff\n",
  1734  		"? \ufeff:\n",
  1735  		"0: \ufeff\n",
  1736  		"? \ufeff: \ufeff\n",
  1737  	}
  1738  	for _, data := range cases {
  1739  		var v interface{}
  1740  		_ = yaml.Unmarshal([]byte(data), &v)
  1741  	}
  1742  }
  1743  
  1744  //var data []byte
  1745  //func init() {
  1746  //	var err error
  1747  //	data, err = ioutil.ReadFile("/tmp/file.yaml")
  1748  //	if err != nil {
  1749  //		panic(err)
  1750  //	}
  1751  //}
  1752  //
  1753  //func (s *S) BenchmarkUnmarshal(c *C) {
  1754  //	var err error
  1755  //	for i := 0; i < c.N; i++ {
  1756  //		var v map[string]interface{}
  1757  //		err = yaml.Unmarshal(data, &v)
  1758  //	}
  1759  //	if err != nil {
  1760  //		panic(err)
  1761  //	}
  1762  //}
  1763  //
  1764  //func (s *S) BenchmarkMarshal(c *C) {
  1765  //	var v map[string]interface{}
  1766  //	yaml.Unmarshal(data, &v)
  1767  //	c.ResetTimer()
  1768  //	for i := 0; i < c.N; i++ {
  1769  //		yaml.Marshal(&v)
  1770  //	}
  1771  //}
  1772  

View as plain text