From fd2e5c983dd8c3a76fc2196557eda5a9f7c58396 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Sun, 20 Oct 2019 22:53:56 +0200
Subject: [PATCH] fix: non-eager matching raw-block-contents

In 4.4.4 the block-contents was matched with an eager match, which means
that with multiple raw-blocks of the same kind, the block was spanned
over the first ending-tag until the last one.
This commit replaces this by a non-eager match.

closes #1579
---
 spec/helpers.js   | 10 +++++++++-
 spec/tokenizer.js |  5 +++++
 src/handlebars.l  |  2 +-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/spec/helpers.js b/spec/helpers.js
index 0e756aba..f95817c6 100644
--- a/spec/helpers.js
+++ b/spec/helpers.js
@@ -47,10 +47,18 @@ describe('helpers', function() {
       runWithIdentityHelper('{{{{identity}}}}{{{{/identity}}}}', '');
     });
 
-    it('helper for nested raw block works if nested raw blocks are broken', function() {
+    xit('helper for nested raw block works if nested raw blocks are broken', function() {
+      // This test was introduced in 4.4.4, but it was not the actual problem that lead to the patch release
+      // The test is deactivated, because in 3.x this template cases an exception and it also does not work in 4.4.3
+      // If anyone can make this template work without breaking everything else, then go for it,
+      // but for now, this is just a known bug, that will be documented.
       runWithIdentityHelper('{{{{identity}}}} {{{{a}}}} {{{{ {{{{/ }}}} }}}} {{{{/identity}}}}', ' {{{{a}}}} {{{{ {{{{/ }}}} }}}} ');
     });
 
+    it('helper for nested raw block closes after first matching close', function() {
+      runWithIdentityHelper('{{{{identity}}}}abc{{{{/identity}}}} {{{{identity}}}}abc{{{{/identity}}}}', 'abc abc');
+    });
+
     it('helper for nested raw block throw exception when with missing closing braces', function() {
       var string = '{{{{a}}}} {{{{/a';
       shouldThrow(function() {
diff --git a/spec/tokenizer.js b/spec/tokenizer.js
index 1a361b75..ec15d597 100644
--- a/spec/tokenizer.js
+++ b/spec/tokenizer.js
@@ -441,4 +441,9 @@ describe('Tokenizer', function() {
     result = tokenize('{{else foo as |bar baz|}}');
     shouldMatchTokens(result, ['OPEN_INVERSE_CHAIN', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE']);
   });
+
+  it('tokenizes raw blocks', function() {
+    var result = tokenize('{{{{a}}}} abc {{{{/a}}}} aaa {{{{a}}}} abc {{{{/a}}}}');
+    shouldMatchTokens(result, ['OPEN_RAW_BLOCK', 'ID', 'CLOSE_RAW_BLOCK', 'CONTENT', 'END_RAW_BLOCK', 'CONTENT', 'OPEN_RAW_BLOCK', 'ID', 'CLOSE_RAW_BLOCK', 'CONTENT', 'END_RAW_BLOCK']);
+  });
 });
diff --git a/src/handlebars.l b/src/handlebars.l
index 2b27a9fa..fbf208b4 100644
--- a/src/handlebars.l
+++ b/src/handlebars.l
@@ -63,7 +63,7 @@ ID    [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD}
                                     return 'END_RAW_BLOCK';
                                   }
                                  }
-<raw>[^\x00]+/("{{{{")          { return 'CONTENT'; }
+<raw>[^\x00]+?/("{{{{")          { return 'CONTENT'; }
 
 <com>[\s\S]*?"--"{RIGHT_STRIP}?"}}" {
   this.popState();
