Repository: shellscape/postcss-less (js)

Issue:
Cannot read property '2' of undefined
While being run through `stylelint` (itself being run in the Atom package `linter-stylelint`) the following stack trace was hit while attempting to parse `.border`:

```
TypeError: Cannot read property '2' of undefined
    at LessParser.rule (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss-less\dist\less-parser.js:64:38)
    at LessParser.createRule (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss-less\dist\less-parser.js:110:18)
    at LessParser.ruleWithoutBody (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss-less\dist\less-parser.js:141:18)
    at LessParser.processEndOfRule (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss-less\dist\less-parser.js:173:22)
    at LessParser.word (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss-less\dist\less-parser.js:272:44)
    at LessParser.loop (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss-less\dist\less-parser.js:300:30)
    at lessParse (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss-less\dist\less-parse.js:23:12)
    at new LazyResult (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss\lib\lazy-result.js:70:24)
    at Processor.process (C:\Users\Landon Abney\.atom\packages\linter-stylelint\node_modules\postcss\lib\processor.js:117:12)
    at file:///C:/Users/Landon Abney/Documents/GitHub-release/linter-stylelint/node_modules/stylelint/lib/getPostcssResult.js:81:29
```

You can reproduce this by:

* Install Atom, `linter-stylelint` and open a new `.less` file.
* Start typing out a class name, at some point during typing it you will get a popup of the `Cannot read property '2' of undefined` error
* You can get a stack trace by placing a breakpoint [here](https://github.com/AtomLinter/linter-stylelint/blob/v3.8.1/lib/index.js#L202)

I'm sure there are more direct ways of triggering this 😛.

_Note: Originally filed as https://github.com/AtomLinter/linter-stylelint/issues/181_

Pull request:
fixes #64: invalid less should throw CSSSyntaxError

Patch:
diff --git a/lib/less-parser.js b/lib/less-parser.js
index 2a18226..5139d09 100755
--- a/lib/less-parser.js
+++ b/lib/less-parser.js
@@ -143,7 +143,7 @@ export default class LessParser extends Parser {
         let bracket = null;
         const brackets = [];
         const start = this.pos;
-        
+
         // we need pass "()" as spaces
         // However we can override method Parser.loop, but it seems less maintainable
         if (this.tokens[start][0] === 'brackets') {
@@ -213,7 +213,8 @@ export default class LessParser extends Parser {
             this.unclosedBracket(bracket);
         }
 
-        if (end) {
+        // dont process an end of rule if there's only one token and it's unknown (#64)
+        if (end && this.tokens.length > 1) {
             const foundEndOfRule = this.processEndOfRule({
                 start,
                 params,


Test patch:
diff --git a/test/postcss.spec.js b/test/postcss.spec.js
index a8ea462..1f7075f 100644
--- a/test/postcss.spec.js
+++ b/test/postcss.spec.js
@@ -1,12 +1,13 @@
 // chai uses expressions for validation
 /* eslint no-unused-expressions: 0 */
 
+import CssSyntaxError from 'postcss/lib/css-syntax-error';
 import {expect} from 'chai';
 import lessSyntax from '../lib/less-syntax';
 import postcss from 'postcss';
 
 describe('#postcss', () => {
-    it('can process LESS syntax', (done) => {
+    it('should process LESS syntax', (done) => {
         const lessText = 'a { b {} }';
 
         postcss()
@@ -19,8 +20,8 @@ describe('#postcss', () => {
                 done();
             }).catch(done);
     });
-    
-    it('can parse LESS mixins as at rules', (done) => {
+
+    it('should parse LESS mixins as at rules', (done) => {
         const lessText = '.foo (@bar; @baz...) { border: @{baz}; }';
 
         postcss()
@@ -33,4 +34,15 @@ describe('#postcss', () => {
                 done();
             }).catch(done);
     });
-});
\ No newline at end of file
+
+    it('should not parse invalid LESS (#64)', (done) => {
+        const lessText = '.foo';
+
+        postcss()
+            .process(lessText, {syntax: lessSyntax})
+            .catch((err) => {
+                expect(err).to.be.an.instanceof(CssSyntaxError);
+                done();
+            });
+    });
+});