diff --git a/changelog_unreleased/vue/12113.md b/changelog_unreleased/vue/12113.md
new file mode 100644
index 000000000..314b5db6d
--- /dev/null
+++ b/changelog_unreleased/vue/12113.md
@@ -0,0 +1,21 @@
+#### Fix hangs on invalid `v-for` (#12113 by @fisker)
+
+
+```jsx
+// Input
+
+
+
+
+// Prettier stable
+// Hangs
+
+// Prettier main
+
+
+;
+```
diff --git a/src/language-html/syntax-vue.js b/src/language-html/syntax-vue.js
index 4bad8ceb3..d26e89c99 100644
--- a/src/language-html/syntax-vue.js
+++ b/src/language-html/syntax-vue.js
@@ -40,8 +40,13 @@ function parseVueFor(value) {
if (!inMatch) {
return;
}
+
const res = {};
res.for = inMatch[3].trim();
+ if (!res.for) {
+ return;
+ }
+
const alias = inMatch[1].trim().replace(stripParensRE, "");
const iteratorMatch = alias.match(forIteratorRE);
if (iteratorMatch) {
@@ -54,10 +59,18 @@ function parseVueFor(value) {
res.alias = alias;
}
+ const left = [res.alias, res.iterator1, res.iterator2];
+ if (
+ left.some(
+ (part, index) =>
+ !part && (index === 0 || left.slice(index + 1).some(Boolean))
+ )
+ ) {
+ return;
+ }
+
return {
- left: `${[res.alias, res.iterator1, res.iterator2]
- .filter(Boolean)
- .join(",")}`,
+ left: left.filter(Boolean).join(","),
operator: inMatch[2],
right: res.for,
};
diff --git a/tests/format/vue/invalid/__snapshots__/jsfmt.spec.js.snap b/tests/format/vue/invalid/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000..cda9412cd
--- /dev/null
+++ b/tests/format/vue/invalid/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,52 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`v-for.vue format 1`] = `
+====================================options=====================================
+parsers: ["vue"]
+printWidth: 80
+ | printWidth
+=====================================input======================================
+
+
+
+
+=====================================output=====================================
+
+
+
+
+================================================================================
+`;
diff --git a/tests/format/vue/invalid/jsfmt.spec.js b/tests/format/vue/invalid/jsfmt.spec.js
new file mode 100644
index 000000000..2fd7eede9
--- /dev/null
+++ b/tests/format/vue/invalid/jsfmt.spec.js
@@ -0,0 +1 @@
+run_spec(__dirname, ["vue"]);
diff --git a/tests/format/vue/invalid/v-for.vue b/tests/format/vue/invalid/v-for.vue
new file mode 100644
index 000000000..2678f1cab
--- /dev/null
+++ b/tests/format/vue/invalid/v-for.vue
@@ -0,0 +1,21 @@
+
+
+