-
Notifications
You must be signed in to change notification settings - Fork 18.6k
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
Conversation
…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) |
There was a problem hiding this comment.
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!!
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 Dockerfile
s in the wild that use it legitimately? Is there actually a case where a float64
is preferred to a string? For reals?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 😉
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
... 👍 😉
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
You should probably make Node values take string only now instead of interface. Should speed the builder up. |
I'm not sure what you mean? Aren't they already? |
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) { |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
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>
e9cf38d
to
05c2d2d
Compare
Updated type switch to be just a type assertion instead. 👍 |
lgtm |
I think we are just waiting on @tiborvass |
@duglin feel free to review and merge at your convenience :) and obviously only if you like it |
What should: RUN [ "-e foo" ] result in? I get different results from the shell vs docker(this pr). |
node.Next = sexp | ||
} | ||
|
||
node.Next = sexp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tianon why this change?
There was a problem hiding this comment.
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.
@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 |
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 |
Although it's strange that we're getting |
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. |
what was the conclusion here? |
@jfrazelle that json sucks, but this PR has 2 l.g.t.m.s already :) |
Nice JSON related issue: #10097 |
i dont know eriks was not all caps |
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)
IHERDAT |
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
inNode.Dump()
, and simplified the builderTestTestData
a little by usingioutil.ReadFile
directly instead ofos.Open
followed immediately byioutil.ReadAll
.