Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust builder to validate that JSON in Dockerfiles are arrays of strings and nothing else to match how we describe them to people (and what all our existing tests already assumed) #9881

Merged
merged 3 commits into from
Jan 15, 2015

Conversation

tianon
Copy link
Member

@tianon tianon commented Jan 3, 2015

This also adds more tests to help verify this, including unicode and nonprintable characters (hence the commit switching to strconv.Quote).

As a bonus, this fixes a subtle bug where [] was turned into [""] and then turned back into [] (and thus [""] was impossible to actually round-trip correctly in a Dockerfile).

In the process, I replaced the custom QuoteString function with the equivalent (but with more special cased characters) strconv.Quote in Node.Dump(), and simplified the builder TestTestData a little by using ioutil.ReadFile directly instead of os.Open followed immediately by ioutil.ReadAll.

…QuoteString function (the only change to existing files is literal tabs becoming \t, but future files may use nonprintable characters and the like now)

Signed-off-by: Andrew "Tianon" Page <admwiggin@gmail.com>
…ad of os.Open+ioutil.ReadAll

Signed-off-by: Andrew "Tianon" Page <admwiggin@gmail.com>
for _, str := range myJson {
switch str.(type) {
case string:
case float64:
str = strconv.FormatFloat(str.(float64), 'G', -1, 64)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THIS IS BREAKING CHANGE!!!111!!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No tests for it, no guarantee of non breakage.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we never describe it this way. Can you find me Dockerfiles in the wild that use it legitimately? Is there actually a case where a float64 is preferred to a string? For reals?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it really makes no sense for a cmd or entrypoint

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or a RUN line either 😉

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everywhere in docs this is just "JSON Array". Also I am +100 on this breaking change. As I was +100 on breaking change for USER+COPY, so don't take my words too serious.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the docs maintainers want me to, I can go on a docs dive replacing JSON array with JSON array of strings... 👍 😉

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so you mean you've broken RUN ["echo", 3.14] ? perhaps mention it in the release notes, someone will trip on it, but I too would expect it to be very few.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have a place where we currently aggregate "next version" release notes, right?

@erikh
Copy link
Contributor

erikh commented Jan 3, 2015

You should probably make Node values take string only now instead of interface. Should speed the builder up.

@tianon
Copy link
Member Author

tianon commented Jan 3, 2015

@erikh
Copy link
Contributor

erikh commented Jan 4, 2015

sorry I misread some of the above code, it's been a while since I was in here.

if err := json.Unmarshal([]byte(rest), &myJson); err != nil {
return nil, nil, err
}

var top, prev *Node
for _, str := range myJson {
switch str.(type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a type switch rather than a single type assertion? I don't think it changes anything besides readability, but I'd find if s, ok := str.(string); !ok { easier (and avoids casting twice).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

@jessfraz
Copy link
Contributor

jessfraz commented Jan 5, 2015

LGTM but maybe just a single type assertion like @icecrime suggested :)

…ings and nothing else to match how we describe them to people (and what all our existing tests already assumed)

This also adds more tests to help verify this, including unicode and nonprintable characters (hence the earlier commit switching to strconv.Quote).

As a bonus, this fixes a subtle bug where [] was turned into [""] and then turned back into [] (and thus [""] was impossible to actually round-trip correctly in a Dockerfile).

Signed-off-by: Andrew "Tianon" Page <admwiggin@gmail.com>
@tianon
Copy link
Member Author

tianon commented Jan 5, 2015

Updated type switch to be just a type assertion instead. 👍

@erikh
Copy link
Contributor

erikh commented Jan 5, 2015

lgtm

@jessfraz
Copy link
Contributor

jessfraz commented Jan 6, 2015

I think we are just waiting on @tiborvass

@jessfraz
Copy link
Contributor

jessfraz commented Jan 9, 2015

@duglin feel free to review and merge at your convenience :) and obviously only if you like it

@duglin
Copy link
Contributor

duglin commented Jan 9, 2015

What should: RUN [ "-e foo" ] result in? I get different results from the shell vs docker(this pr).
Should this PR have fixed this ambiguity?

node.Next = sexp
}

node.Next = sexp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tianon why this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if was here to check for the case of [] turning into [""] and turning it back into []. By fixing parseJSON to return nil (the linked-list representation of an empty list), this if is no longer required, so now [] and [""] can both round-trip successfully.

@tianon
Copy link
Member Author

tianon commented Jan 9, 2015

@duglin that's a valid JSON array of strings, and there's no way for us to detect that it should be parsed by the shell as-is instead, so that becomes the literal command -e foo (which very likely won't exist in PATH)

@tianon
Copy link
Member Author

tianon commented Jan 9, 2015

Which is the current behavior without this PR, too:

$ docker build -
FROM busybox
RUN [ "-e foo" ]
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM busybox
 ---> 4986bf8c1536
Step 1 : RUN -e foo
 ---> Running in 439e68f47660
/bin/sh: illegal option - 
INFO[0006] The command [/bin/sh -c -e foo] returned a non-zero code: 2 

@tianon
Copy link
Member Author

tianon commented Jan 9, 2015

Although it's strange that we're getting /bin/sh there when we shouldn't be...

@duglin
Copy link
Contributor

duglin commented Jan 9, 2015

Yes that's what we get today too - I was just wondering if this PR was attempting to fix that issue as well. Its not, and probably can't, but was just hoping you found some magic.

@jessfraz
Copy link
Contributor

what was the conclusion here?

@LK4D4
Copy link
Contributor

LK4D4 commented Jan 14, 2015

@jfrazelle that json sucks, but this PR has 2 l.g.t.m.s already :)

@thaJeztah
Copy link
Member

Nice JSON related issue: #10097

@jessfraz
Copy link
Contributor

i dont know eriks was not all caps

jessfraz pushed a commit that referenced this pull request Jan 15, 2015
Adjust builder to validate that JSON in Dockerfiles are arrays of strings and nothing else to match how we describe them to people (and what all our existing tests already assumed)
@jessfraz jessfraz merged commit 640e0fc into moby:master Jan 15, 2015
@tianon tianon deleted the json-array-of-strings branch January 15, 2015 01:14
@erikh
Copy link
Contributor

erikh commented Jan 15, 2015

IHERDAT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants