RotherOSS / otobo

OTOBO is one of the most flexible web-based ticketing systems used for Customer Service, Help Desk, IT Service Management. https://otobo.io/
GNU General Public License v3.0
250 stars 72 forks source link

Wrong decoded values for booleans in JSON.pm in nested JSON #3613

Closed Lucsaan closed 2 months ago

Lucsaan commented 2 months ago

When I am using JSON.pm

my $PerlStructureScalar = $JSONObject->Decode(
        Data => '{"Key1":"Value1","Key2":42,"Key3":"Another Value", "Key4":true, "Key5":false}'
    );

For example:

my $JSONString = '{
"data":{
  "newActivity":{
    "OK":true,
    "Error":"Currently no Error Supported",
    "Result":null}
  }
}';

I get a result like this:

{
  'data' => {
    'newActivity' => {
        'Result' => undef,
        'Error' => 'Currently no Error Supported',
        'OK' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' )
       }
    }
  }

Maybe a problem with nested JSON. Worked with OTOBO 10.1.x with only JSON module. Doesn't work with OTOBO 11.0.x JSON::XS

svenoe commented 2 months ago

What do you want to achieve?

my $Perl = $Kernel::OM->Get('Kernel::System::JSON')->Decode(
    Data => '{"x": true}',
);
use Data::Dumper;
print STDERR Dumper($Perl);
print STDERR "=> $Perl->{x}\n";

Output:

$VAR1 = {
          'x' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' )
        };
=> 1
Lucsaan commented 2 months ago

Hi Sven :-)

Thats really funny now.

I used this code to put the value in a %GetParam hash.

$GetParam{Success} = $Response->{Data}->{data}->{newActivity}->{OK} || 0;

and got this:

[16:02:11 15.07.2024] Typ: HASH - Variable: %GetParam 
{
  'Success' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
}
'----------------------------------- END %GetParam -----------------------------------'

and used it as Bind for the $DBObject to put a new entry into the table:

my $DBObject = $Kernel::OM->Get('Kernel::System::DB');

    $DBObject->Do(
        SQL  => 'INSERT INTO table (success) VALUES (?)',
        Bind => [\$GetParam{Success}],
    );

Then I got this error:

ERROR: OTOBO-CGI-07 Perl: 5.34.0 OS: linux Time: Mon Jul 15 14:02:11 2024$
 Message: No SCALAR param in Bind!

Now after your answer I tried it again. And it worked. There was the value "1" in $GetParam{Success} and the binding . Maybe it was to warm for my Mac on Monday ;-)

Now it works as intended. Sorry for the inconvenience.

You can close this issue if you want.

bschmalhofer commented 2 months ago

The deserialization of the JSON looks fine. Perl, with version less then 5.40, has no builtin booleans. Therefore a special construct, https://metacpan.org/dist/JSON-PP/source/lib/JSON/PP.pm#L1459, must be used to distinguish booleans from the integers 1 and 0. As far as I recall the Perl DBI module has no problem those booleans. But I think that the check in https://github.com/RotherOSS/otobo/blob/e604299f75a5f663d81cb9ccf8174057f1047ac1/Kernel/System/DB.pm#L537 is too strict. Booleans should be accepted as bind variable.

I propose to add tests for that case in a test script and to allow boolean bind variables in OTOBO 11.1.x. The check for booleans could be done with https://metacpan.org/pod/Types::Serialiser#$is_bool-=-Types::Serialiser::is_bool-$value.

svenoe commented 2 months ago

No problem Lucsaan, and let's discuss this separately, Bernhard.