diff --git a/engine/env.go b/engine/env.go index 9b8f639724..a16dc35cd9 100644 --- a/engine/env.go +++ b/engine/env.go @@ -187,6 +187,12 @@ func (env *Env) Decode(src io.Reader) error { } func (env *Env) SetAuto(k string, v interface{}) { + // Issue 7941 - if the value in the incoming JSON is null then treat it + // as if they never specified the property at all. + if v == nil { + return + } + // FIXME: we fix-convert float values to int, because // encoding/json decodes integers to float64, but cannot encode them back. // (See http://golang.org/src/pkg/encoding/json/decode.go#L46) diff --git a/integration/api_test.go b/integration/api_test.go index 9748141b1d..c326465526 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "encoding/json" + "fmt" "io" "io/ioutil" "net" @@ -425,6 +426,67 @@ func TestPostJsonVerify(t *testing.T) { } } +// Issue 7941 - test to make sure a "null" in JSON is just ignored. +// W/o this fix a null in JSON would be parsed into a string var as "null" +func TestPostCreateNull(t *testing.T) { + eng := NewTestEngine(t) + daemon := mkDaemonFromEngine(eng, t) + defer daemon.Nuke() + + configStr := fmt.Sprintf(`{ + "Hostname":"", + "Domainname":"", + "Memory":0, + "MemorySwap":0, + "CpuShares":0, + "Cpuset":null, + "AttachStdin":true, + "AttachStdout":true, + "AttachStderr":true, + "PortSpecs":null, + "ExposedPorts":{}, + "Tty":true, + "OpenStdin":true, + "StdinOnce":true, + "Env":[], + "Cmd":"ls", + "Image":"%s", + "Volumes":{}, + "WorkingDir":"", + "Entrypoint":null, + "NetworkDisabled":false, + "OnBuild":null}`, unitTestImageID) + + req, err := http.NewRequest("POST", "/containers/create", strings.NewReader(configStr)) + if err != nil { + t.Fatal(err) + } + + req.Header.Set("Content-Type", "application/json") + + r := httptest.NewRecorder() + if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil { + t.Fatal(err) + } + assertHttpNotError(r, t) + if r.Code != http.StatusCreated { + t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code) + } + + var apiRun engine.Env + if err := apiRun.Decode(r.Body); err != nil { + t.Fatal(err) + } + containerID := apiRun.Get("Id") + + containerAssertExists(eng, containerID, t) + + c := daemon.Get(containerID) + if c.Config.Cpuset != "" { + t.Fatalf("Cpuset should have been empty - instead its:" + c.Config.Cpuset) + } +} + func TestPostContainersKill(t *testing.T) { eng := NewTestEngine(t) defer mkDaemonFromEngine(eng, t).Nuke()