jhthorsen / openapi-client

A client for talking to an Open API powered server
11 stars 17 forks source link

no try to decode_json any false value #5

Closed mohawk2 closed 6 years ago

mohawk2 commented 6 years ago

Raison d'etre: when installing OpenAPI::Client in a Docker container, this code:

  $content //= !-t STDIN && select($r, undef, undef, 0) ? join '', <STDIN> : undef;

gets, while running the tests, not undef but an empty string. decode_json is currently called on all defined values, and throws an exception. I cannot see any reason to try to decode any value that is false.

jhthorsen commented 6 years ago

Empty string is not false. It's an empty string.

I don't think I can merge this, but I'll leave it open for a while.

mohawk2 commented 6 years ago

Sorry, I'm not sure I understand. Are you saying that '' is a true value? Currently you are calling decode_json on all defined values. That seems to me not correct, and definitely causes an error when called on an empty string. False values in Perl, as far as I know, are undef, empty string, number zero, and string with only zero. It seems to me that calling decode_json on any of those is undesirable. What is your thought?

jhthorsen commented 6 years ago

I could be wrong, but please run this, and hit enter once:

$ perl -MMojo::JSON=encode_json,true -le'$s=<>;chomp $s;print encode_json $_ for undef, "", 0, true, $s'
null
""
0
true
""

To me, this means that it's perfectly valid to send an empty string as body.

mohawk2 commented 6 years ago

I agree! So long as it's a JSON-encoded empty string, which is actually two double-quotes. An actual empty string is an error:

use Mojo::JSON qw(decode_json);
use Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
for (undef, "", 0, "hi", '{"a": 7}', '""') {
  my $got = eval { decode_json $_ };
  my $err = $@; chomp $err if $err;
  print "decode_json ", Dumper($_), ": ", Dumper($got), ($@ ? " (error: $err)" : ""), "\n";
}

This is the output:

decode_json undef: undef (error: Missing or empty input at tf line 6.)
decode_json '': undef (error: Missing or empty input at tf line 6.)
decode_json 0: 0
decode_json 'hi': undef (error: Malformed JSON: Expected string, array, object, number, boolean or null at line 0, offset 0 at tf line 6.)
decode_json '{"a": 7}': {'a' => 7}
decode_json '""': ''

What your code is currently providing to decode_json is an empty string, which it does not like - see second case above.

jhthorsen commented 6 years ago

Oh. Yeah 🙈

Can you provide a failing test as well? I will probably reverse this later on if there's no test.

mohawk2 commented 6 years ago

Updated with a test.

jhthorsen commented 6 years ago

Thanks 👍