Skip to content

Commit b8f2cdf

Browse files
author
Janek Lasocki-Biczysko
committed
fixes #3
1 parent 57ee005 commit b8f2cdf

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

src/janeklb/json/JSONCharInputReader.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class JSONCharInputReader
2020
private $outputInterface;
2121
private $state;
2222
private $depth;
23+
private $quoteCount;
2324

2425
/**
2526
* Create a JSONCharInputReader object
@@ -34,6 +35,7 @@ public function __construct(JSONChunkProcessor $outputInterface)
3435
$this->state = self::STATE_OUTSIDE;
3536
$this->outputInterface = $outputInterface;
3637
$this->depth = 0;
38+
$this->quoteCount = 0;
3739
}
3840

3941
/**
@@ -62,27 +64,39 @@ public function readChar($char)
6264
case self::STATE_INCURLY:
6365
case self::STATE_INSQUARE:
6466

67+
if ($char == '"' && !$this->lastCharIs('\\'))
68+
$this->quoteCount++;
69+
6570
$this->buffer .= $char;
6671

72+
// if quote count is odd we're inside a string....
73+
if ($this->quoteCount % 2)
74+
break;
75+
6776
$closing = $this->state == self::STATE_INCURLY ? '}' : ']';
6877
$opening = $this->state == self::STATE_INCURLY ? '{' : '[';
6978

7079
if ($char == $opening)
7180
// if this is another opening brace/bracket character, increase the depth
7281
$this->depth++;
7382
else if ($char == $closing && --$this->depth == 0)
83+
{
7484
// if this is a closing character, decrease the depth and process the buffer if
7585
// the bottom was reached
7686
$this->processBuffer();
87+
$this->quoteCount = 0;
88+
}
7789

7890
break;
7991

8092
// Inside a string
8193
case self::STATE_INSTRING:
82-
$this->buffer .= $char;
83-
if ($char == '"')
94+
95+
if ($char == '"' && !$this->lastCharIs('\\'))
8496
$this->state = self::STATE_WAITING;
8597

98+
$this->buffer .= $char;
99+
86100
break;
87101

88102
// Waiting on any input within a JSON stream
@@ -136,6 +150,15 @@ public function readChar($char)
136150
}
137151
}
138152

153+
private function lastCharIs($char) {
154+
$len = strlen($this->buffer);
155+
if ($len == 0)
156+
return false;
157+
158+
$lastChar = $this->buffer[$len - 1];
159+
return $lastChar === $char;
160+
}
161+
139162
/**
140163
* Process the JSON data stream's buffer and reset the state
141164
*

test/suite.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
require 'PHPUnit/Autoload.php';
4+
5+
$suite = new PHPUnit_Framework_TestSuite('JSONCharInputReader Test Suite');
6+
$suite->addTestFile(__DIR__ . "/test.php");
7+
PHPUnit_TextUI_TestRunner::run($suite);

test/test.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ public function testMixed()
105105
}
106106

107107
public function testEscaped()
108+
{
109+
$this->sendInput('"abc\"def",');
110+
$this->assertObjects('abc"def');
111+
}
112+
113+
public function testEscapedInObject()
108114
{
109115
$this->sendInput('{"x": "x\"a"},{"a\"b":1}');
110116

@@ -118,6 +124,18 @@ public function testEscaped()
118124
}
119125

120126
public function testBracketsAndBracesInString()
127+
{
128+
$this->sendInput('"str}ing", "str]ing", ');
129+
$this->assertObjects("str}ing", "str]ing");
130+
}
131+
132+
public function testBracketsAndBracesInArrayString()
133+
{
134+
$this->sendInput('["str}ing"], ["str]ing"], ["str]ing", "str}ing"]');
135+
$this->assertObjects(array("str}ing"), array("str]ing"), array("str]ing", "str}ing"));
136+
}
137+
138+
public function testBracketsAndBracesInObjectString()
121139
{
122140
$this->sendInput('{"bracket": "val]ue", "brace": "val}ue"}');
123141

0 commit comments

Comments
 (0)