Completed
Push — master ( 2b6e28...3d0129 )
by
unknown
10:26
created

Contrib/less.php/Exception/Chunk.php (7 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Chunk Exception
5
 *
6
 * @package Less
7
 * @subpackage exception
8
 */
9
class Less_Exception_Chunk extends Less_Exception_Parser{
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
10
11
12
	protected $parserCurrentIndex = 0;
13
14
	protected $emitFrom = 0;
15
16
	protected $input_len;
17
18
19
	/**
20
	 * Constructor
21
	 *
22
	 * @param string $input
23
	 * @param Exception $previous Previous exception
24
	 * @param integer $index The current parser index
25
	 * @param Less_FileInfo|string $currentFile The file
26
	 * @param integer $code The exception code
27
	 */
28
	public function __construct($input, Exception $previous = null, $index = null, $currentFile = null, $code = 0){
29
30
		$this->message = 'ParseError: Unexpected input'; //default message
31
32
		$this->index = $index;
33
34
		$this->currentFile = $currentFile;
0 ignored issues
show
Documentation Bug introduced by
It seems like $currentFile can also be of type object<Less_FileInfo> or string. However, the property $currentFile is declared as type object<Less_ImportedFile>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
35
36
		$this->input = $input;
37
		$this->input_len = strlen($input);
38
39
		$this->Chunks();
40
		$this->genMessage();
41
	}
42
43
44
	/**
45
	 * See less.js chunks()
46
	 * We don't actually need the chunks
47
	 *
48
	 */
49
	protected function Chunks(){
50
		$level = 0;
51
		$parenLevel = 0;
52
		$lastMultiCommentEndBrace = null;
53
		$lastOpening = null;
54
		$lastMultiComment = null;
55
		$lastParen = null;
56
57
		for( $this->parserCurrentIndex = 0; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++ ){
0 ignored issues
show
Comprehensibility Bug introduced by
Loop incrementor ($this) jumbling with inner loop
Loading history...
58
			$cc = $this->CharCode($this->parserCurrentIndex);
59
			if ((($cc >= 97) && ($cc <= 122)) || ($cc < 34)) {
60
				// a-z or whitespace
61
				continue;
62
			}
63
64
			switch ($cc) {
65
66
				// (
67
				case 40:
68
					$parenLevel++;
69
					$lastParen = $this->parserCurrentIndex;
70
					continue;
71
72
				// )
73
				case 41:
74
					$parenLevel--;
75
					if( $parenLevel < 0 ){
76
						return $this->fail("missing opening `(`");
77
					}
78
					continue;
79
80
				// ;
81
				case 59:
82
					//if (!$parenLevel) { $this->emitChunk();	}
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
83
					continue;
84
85
				// {
86
				case 123:
87
					$level++;
88
					$lastOpening = $this->parserCurrentIndex;
89
					continue;
90
91
				// }
92
				case 125:
93
					$level--;
94
					if( $level < 0 ){
95
						return $this->fail("missing opening `{`");
96
97
					}
98
					//if (!$level && !$parenLevel) { $this->emitChunk(); }
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
99
					continue;
100
				// \
101
				case 92:
102
					if ($this->parserCurrentIndex < $this->input_len - 1) { $this->parserCurrentIndex++; continue; }
103
					return $this->fail("unescaped `\\`");
104
105
				// ", ' and `
106
				case 34:
107
				case 39:
108
				case 96:
109
					$matched = 0;
110
					$currentChunkStartIndex = $this->parserCurrentIndex;
111
					for ($this->parserCurrentIndex = $this->parserCurrentIndex + 1; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) {
112
						$cc2 = $this->CharCode($this->parserCurrentIndex);
113
						if ($cc2 > 96) { continue; }
114
						if ($cc2 == $cc) { $matched = 1; break; }
115
						if ($cc2 == 92) {        // \
116
							if ($this->parserCurrentIndex == $this->input_len - 1) {
117
								return $this->fail("unescaped `\\`");
118
							}
119
							$this->parserCurrentIndex++;
120
						}
121
					}
122
					if ($matched) { continue; }
123
					return $this->fail("unmatched `" + chr($cc) + "`", $currentChunkStartIndex);
124
125
				// /, check for comment
126
				case 47:
127
					if ($parenLevel || ($this->parserCurrentIndex == $this->input_len - 1)) { continue; }
128
					$cc2 = $this->CharCode($this->parserCurrentIndex+1);
129
					if ($cc2 == 47) {
130
						// //, find lnfeed
131
						for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) {
132
							$cc2 = $this->CharCode($this->parserCurrentIndex);
133
							if (($cc2 <= 13) && (($cc2 == 10) || ($cc2 == 13))) { break; }
134
						}
135
					} else if ($cc2 == 42) {
136
						// /*, find */
137
						$lastMultiComment = $currentChunkStartIndex = $this->parserCurrentIndex;
138
						for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len - 1; $this->parserCurrentIndex++) {
139
							$cc2 = $this->CharCode($this->parserCurrentIndex);
140
							if ($cc2 == 125) { $lastMultiCommentEndBrace = $this->parserCurrentIndex; }
141
							if ($cc2 != 42) { continue; }
142
							if ($this->CharCode($this->parserCurrentIndex+1) == 47) { break; }
143
						}
144
						if ($this->parserCurrentIndex == $this->input_len - 1) {
145
							return $this->fail("missing closing `*/`", $currentChunkStartIndex);
146
						}
147
					}
148
					continue;
149
150
				// *, check for unmatched */
151
				case 42:
152
					if (($this->parserCurrentIndex < $this->input_len - 1) && ($this->CharCode($this->parserCurrentIndex+1) == 47)) {
153
						return $this->fail("unmatched `/*`");
154
					}
155
					continue;
156
			}
157
		}
158
159
		if( $level !== 0 ){
160
			if( ($lastMultiComment > $lastOpening) && ($lastMultiCommentEndBrace > $lastMultiComment) ){
161
				return $this->fail("missing closing `}` or `*/`", $lastOpening);
162
			} else {
163
				return $this->fail("missing closing `}`", $lastOpening);
164
			}
165
		} else if ( $parenLevel !== 0 ){
166
			return $this->fail("missing closing `)`", $lastParen);
167
		}
168
169
170
		//chunk didn't fail
171
172
173
		//$this->emitChunk(true);
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
174
	}
175
176
	public function CharCode($pos){
177
		return ord($this->input[$pos]);
178
	}
179
180
181
	public function fail( $msg, $index = null ){
182
183
		if( !$index ){
184
			$this->index = $this->parserCurrentIndex;
185
		}else{
186
			$this->index = $index;
187
		}
188
		$this->message = 'ParseError: '.$msg;
189
	}
190
191
192
	/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
193
	function emitChunk( $force = false ){
194
		$len = $this->parserCurrentIndex - $this->emitFrom;
195
		if ((($len < 512) && !$force) || !$len) {
196
			return;
197
		}
198
		$chunks[] = substr($this->input, $this->emitFrom, $this->parserCurrentIndex + 1 - $this->emitFrom );
199
		$this->emitFrom = $this->parserCurrentIndex + 1;
200
	}
201
	*/
202
203
}
204