patch 8.2.0791: a second popup window with terminal causes trouble

Problem:    A second popup window with terminal causes trouble.
Solution:   Disallow opening a second terminal-popup window. (closes #6101,
            closes #6103) Avoid defaulting to an invalid line number.
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 94a3367..5447b74 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -2918,8 +2918,12 @@
 	{
 	    case ADDR_LINES:
 	    case ADDR_OTHER:
-		// default is current line number
-		eap->line2 = curwin->w_cursor.lnum;
+		// Default is the cursor line number.  Avoid using an invalid
+		// line number though.
+		if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+		    eap->line2 = curbuf->b_ml.ml_line_count;
+		else
+		    eap->line2 = curwin->w_cursor.lnum;
 		break;
 	    case ADDR_WINDOWS:
 		eap->line2 = CURRENT_WIN_NR;
diff --git a/src/popupwin.c b/src/popupwin.c
index 4ee097a..79021c3 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -1758,6 +1758,25 @@
 }
 
 /*
+ * Return TRUE if there is any popup window with a terminal buffer.
+ */
+    static int
+popup_terminal_exists(void)
+{
+    win_T	*wp;
+    tabpage_T	*tp;
+
+    FOR_ALL_POPUPWINS(wp)
+	if (wp->w_buffer->b_term != NULL)
+	    return TRUE;
+    FOR_ALL_TABPAGES(tp)
+	FOR_ALL_POPUPWINS_IN_TAB(tp, wp)
+	    if (wp->w_buffer->b_term != NULL)
+		return TRUE;
+    return FALSE;
+}
+
+/*
  * popup_create({text}, {options})
  * popup_atcursor({text}, {options})
  * etc.
@@ -1786,6 +1805,13 @@
 		semsg(_(e_nobufnr), argvars[0].vval.v_number);
 		return NULL;
 	    }
+#ifdef FEAT_TERMINAL
+	    if (buf->b_term != NULL && popup_terminal_exists())
+	    {
+		emsg(_("E861: Cannot open a second popup with a terminal"));
+		return NULL;
+	    }
+#endif
 	}
 	else if (!(argvars[0].v_type == VAR_STRING
 			&& argvars[0].vval.v_string != NULL)
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index feaa5e4..8c917bc 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -2426,10 +2426,10 @@
   let g:test_is_flaky = 1
 
   let origwin = win_getid()
-  let ptybuf = term_start(&shell, #{hidden: 1})
-  let winid = popup_create(ptybuf, #{minwidth: 40, minheight: 10})
+  let termbuf = term_start(&shell, #{hidden: 1})
+  let winid = popup_create(termbuf, #{minwidth: 40, minheight: 10})
   " Wait for shell to start
-  call WaitForAssert({-> assert_equal("run", job_status(term_getjob(ptybuf)))})
+  call WaitForAssert({-> assert_equal("run", job_status(term_getjob(termbuf)))})
   sleep 100m
   " Check this doesn't crash
   call assert_equal(winnr(), winnr('j'))
@@ -2440,11 +2440,16 @@
   " Cannot quit while job is running
   call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:')
 
-  " Cannot enter Terminal-Normal mode.
+  " Cannot enter Terminal-Normal mode. (TODO: but it works...)
   call feedkeys("xxx\<C-W>N", 'xt')
   call assert_fails('call feedkeys("gf", "xt")', 'E863:')
   call feedkeys("a\<C-U>", 'xt')
 
+  " Cannot open a second one.
+  let termbuf2 = term_start(&shell, #{hidden: 1})
+  call assert_fails('call popup_create(termbuf2, #{})', 'E861:')
+  call term_sendkeys(termbuf2, "exit\<CR>")
+
   " Exiting shell closes popup window
   call feedkeys("exit\<CR>", 'xt')
   " Wait for shell to exit
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index ab1961a..7f85f6c 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -2587,9 +2587,8 @@
   let buf1 = term_start(&shell, #{hidden: 1})
   let win1 = popup_create(buf1, {})
   let buf2 = term_start(&shell, #{hidden: 1})
-  let win2 = popup_create(buf2, {})
+  call assert_fails('call popup_create(buf2, {})', 'E861:')
   call popup_close(win1)
-  call popup_close(win2)
   exe buf1 .. 'bwipe!'
   exe buf2 .. 'bwipe!'
 endfunc
@@ -2619,10 +2618,8 @@
   CheckExecutable sh
 
   set hidden
-  let g:buf0 = term_start('sh', #{hidden: 1})
+  let g:buf0 = term_start('sh', #{hidden: 1, term_finish: 'close'})
   call popup_create(g:buf0, {})
-  let g:buf1 = term_start('sh', #{hidden: 1, term_finish: 'close'})
-  call popup_create(g:buf1, {})
   call assert_fails("call term_start(['sh', '-c'], #{curwin: 1})", 'E863:')
 
   call popup_clear(1)
diff --git a/src/version.c b/src/version.c
index aa03f90..92f5660 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    791,
+/**/
     790,
 /**/
     789,