Skip to content

Commit

Permalink
Fix JsonBinaryDecoder when there is NULL in data or if there is long …
Browse files Browse the repository at this point in the history
…array with small numbers (#96)

Thank you
  • Loading branch information
matyx authored Jan 12, 2024
1 parent 4107322 commit 4ea690f
Showing 1 changed file with 19 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ public static function makeJsonBinaryDecoder(string $data): self
*/
public function parseToString(): string
{
// Sometimes, we can insert a NULL JSON even we set the JSON field as NOT NULL.
// If we meet this case, we can return a 'null' value.
if($this->binaryDataReader->getBinaryDataLength() === 0) {
return 'null';
}
$this->parseJson($this->binaryDataReader->readUInt8());

return $this->jsonBinaryDecoderFormatter->getJsonString();
Expand Down Expand Up @@ -198,7 +203,7 @@ private function parseArrayOrObject(int $type, int $intSize): array

$entries = [];
for ($i = 0; $i !== $elementCount; ++$i) {
$entries[$i] = $this->getOffsetOrInLinedValue($bytes, $intSize);
$entries[$i] = $this->getOffsetOrInLinedValue($bytes, $intSize, $valueEntrySize);
}

$keys = [];
Expand Down Expand Up @@ -238,11 +243,21 @@ private static function valueEntrySize(bool $large): int
* @throws BinaryDataReaderException
* @throws JsonBinaryDecoderException
*/
private function getOffsetOrInLinedValue(int $bytes, int $intSize): JsonBinaryDecoderValue
private function getOffsetOrInLinedValue(int $bytes, int $intSize, int $valueEntrySize): JsonBinaryDecoderValue
{
$type = $this->binaryDataReader->readUInt8();

if (self::isInLinedType($type, $intSize)) {
return $this->parseScalar($type);
$scalar = $this->parseScalar($type);

// In binlog format, JSON arrays are fixed width elements, even though type value can be smaller.
// In order to properly process this case, we need to move cursor to the next element, which is on position 1 + $valueEntrySize (1 is length of type)
if($type === self::UINT16 || $type === self::INT16) {
$readNextBytes = $valueEntrySize - 2 - 1;
$this->binaryDataReader->read($readNextBytes);
}

return $scalar;
}

$offset = $this->binaryDataReader->readUIntBySize($intSize);
Expand Down Expand Up @@ -371,4 +386,4 @@ private function ensureOffset(?int $ensureOffset): void
$this->binaryDataReader->advance($ensureOffset + 1 - $pos);
}
}
}
}

0 comments on commit 4ea690f

Please sign in to comment.