Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Sep 2022 01:52:06 GMT
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: f447ddc7b861 - stable/13 - MFV: less v608
Message-ID:  <202209200152.28K1q6a9007430@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by delphij:

URL: https://cgit.FreeBSD.org/src/commit/?id=f447ddc7b861ccdf4f433988776ad537588a2919

commit f447ddc7b861ccdf4f433988776ad537588a2919
Author:     Xin LI <delphij@FreeBSD.org>
AuthorDate: 2022-09-06 05:52:39 +0000
Commit:     Xin LI <delphij@FreeBSD.org>
CommitDate: 2022-09-20 01:51:53 +0000

    MFV: less v608
    
    Relnotes:       yes
    (cherry picked from commit 95270f73baf6fa95ae529bc2eb6a61f5c79f32c0)
---
 contrib/less/LICENSE         |   2 +-
 contrib/less/NEWS            |  67 ++++++++++
 contrib/less/README          |   6 +-
 contrib/less/brac.c          |   6 +-
 contrib/less/ch.c            |  19 ++-
 contrib/less/charset.c       |  18 +--
 contrib/less/charset.h       |   2 +-
 contrib/less/cmd.h           |   3 +-
 contrib/less/cmdbuf.c        |  91 ++++++++++----
 contrib/less/command.c       |  76 +++++++++---
 contrib/less/compose.uni     |  20 ++-
 contrib/less/cvt.c           |   2 +-
 contrib/less/decode.c        |  30 ++++-
 contrib/less/edit.c          |   4 +-
 contrib/less/filename.c      |  19 ++-
 contrib/less/fmt.uni         |   3 +-
 contrib/less/forwback.c      | 126 +++++++++++++++++--
 contrib/less/funcs.h         |  18 ++-
 contrib/less/help.c          |  20 ++-
 contrib/less/ifile.c         |   2 +-
 contrib/less/input.c         |  22 ++--
 contrib/less/jump.c          |   2 +-
 contrib/less/less.h          |   4 +-
 contrib/less/less.hlp        |  18 ++-
 contrib/less/less.nro        |  99 ++++++++++++---
 contrib/less/lessecho.c      |  45 +++++--
 contrib/less/lessecho.nro    |   2 +-
 contrib/less/lesskey.c       |  11 +-
 contrib/less/lesskey.h       |   2 +-
 contrib/less/lesskey.nro     | 155 ++++++++++++++++-------
 contrib/less/lesskey_parse.c | 238 +++++++++++++++++++++++++++---------
 contrib/less/lglob.h         |   2 +-
 contrib/less/line.c          | 285 ++++++++++++++++++++++++++++++++-----------
 contrib/less/linenum.c       |  23 +++-
 contrib/less/lsystem.c       |   9 +-
 contrib/less/main.c          |  25 +++-
 contrib/less/mark.c          |   5 +-
 contrib/less/optfunc.c       | 131 ++++++++++++++++++--
 contrib/less/option.c        |   4 +-
 contrib/less/option.h        |   2 +-
 contrib/less/opttbl.c        |  65 +++++++++-
 contrib/less/os.c            |  18 ++-
 contrib/less/output.c        |  11 +-
 contrib/less/pattern.c       |  13 +-
 contrib/less/pattern.h       |  34 ++++--
 contrib/less/pckeys.h        |   2 +-
 contrib/less/position.c      |   3 +-
 contrib/less/position.h      |   2 +-
 contrib/less/prompt.c        |  29 ++---
 contrib/less/screen.c        |  62 ++++++++--
 contrib/less/scrsize.c       |   2 +-
 contrib/less/search.c        |  59 +++++----
 contrib/less/signal.c        |   2 +-
 contrib/less/tags.c          |   8 +-
 contrib/less/ttyin.c         |  63 ++++++----
 contrib/less/ubin.uni        |   2 +-
 contrib/less/version.c       |  27 +++-
 contrib/less/wide.uni        |  25 ++--
 contrib/less/xbuf.c          |  23 +++-
 contrib/less/xbuf.h          |   3 +-
 usr.bin/less/defines.h       |   4 +
 61 files changed, 1586 insertions(+), 489 deletions(-)

diff --git a/contrib/less/LICENSE b/contrib/less/LICENSE
index 315d1d86815c..65bce4288972 100644
--- a/contrib/less/LICENSE
+++ b/contrib/less/LICENSE
@@ -2,7 +2,7 @@
                           ------------
 
 Less
-Copyright (C) 1984-2018  Mark Nudelman
+Copyright (C) 1984-2022  Mark Nudelman
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
diff --git a/contrib/less/NEWS b/contrib/less/NEWS
index a403c5d8a875..bcfe4c6c9e38 100644
--- a/contrib/less/NEWS
+++ b/contrib/less/NEWS
@@ -9,6 +9,73 @@
   Report bugs, suggestions or comments at 
   https://github.com/gwsw/less/issues.
 
+======================================================================
+
+	Major changes between "less" versions 590 and 608
+
+* Add the --header option (github #43).
+
+* Add the --no-number-headers option (github #178).
+
+* Add the --status-line option.
+
+* Add the --redraw-on-quit option (github #36).
+
+* Add the --search-options option (github #213).
+
+* Add the --exit-follow-on-close option (github #244).
+
+* Add 'H' color type to set color of header lines.
+
+* Add #version conditional to lesskey.
+
+* Add += syntax to variable section in lesskey files.
+
+* Allow option name in -- command to end with '=' in addition to '\n'.
+
+* Add $HOME/.config to possible locations of lesskey file (github #153).
+
+* Add $XDG_STATE_HOME and $HOME/.local/state to possible locations
+  of history file (github #223).
+
+* Don't read or write history file in secure mode (github #201).
+
+* Fix display of multibyte and double-width chars in prompt.
+
+* Fix ESC-BACKSPACE command when BACKSPACE key does not send 0x08
+  (github #188).
+
+* Add more \k codes to lesskey format.
+
+* Fix bug when empty file is modified while viewing it.
+
+* Fix bug when parsing a malformed lesskey file (githb #234).
+
+* Fix bug scrolling history when --incsearch is set (github #214).
+
+* Fix buffer overflow when invoking lessecho with more than 63 -m/-n 
+  options (github #198).
+
+* Fix buffer overflow in bin_file (github #271).
+
+* Fix bug restoring color at end of highlighted text.
+
+* Fix bug in parsing lesskey file.
+
+* Defer moving cursor to lower left in some more cases.
+
+* Suppress TAB filename expansion in some cases where it doesn't make sense.
+
+* Fix termlib detection when compiler doesn't accept 
+  calls to undeclared functions.
+
+* Fix bug in input of non-ASCII characters on Windows (github #247)
+
+* Escape filenames when invoking LESSCLOSE.
+
+* Fix bug using multibyte UTF-8 char in search string 
+  with --incsearch (github #273).
+
 ======================================================================
 
 	Major changes between "less" versions 581 and 590
diff --git a/contrib/less/README b/contrib/less/README
index 4a5aa62a44ee..4bfdc5e5a67f 100644
--- a/contrib/less/README
+++ b/contrib/less/README
@@ -8,7 +8,7 @@
 **************************************************************************
 
     This is the source code distribution of "less".
-    This program is part of the GNU project (http://www.gnu.org).
+    This program is part of the GNU project (https://www.gnu.org).
 
     This program is free software.  You may redistribute it and/or
     modify it under the terms of either:
@@ -28,7 +28,7 @@
 You should build from a clone of a git repository 
 ONLY IF you are doing development on the less source itself.
 If you are merely using less as a tool, you should download a release
-from http://greenwoodsoftware.com and NOT from github.
+from https://greenwoodsoftware.com and NOT from github.
 
 The formatted manual page is in less.man.
 The manual page nroff source is in less.nro.
@@ -41,7 +41,7 @@ INSTALLATION (Unix & Linux systems only):
    if you have not already done so.  
 
 2. If you are building from a clone of a git repository,
-   type "make -f Makefile.aut".
+   type "make -f Makefile.aut distfiles".
    If you are building from a numbered release package (a tar or 
    zip file with a name like less-999.tar.gz or less-999.zip downloaded 
    from greenwoodsoftware.com, not from github), you should skip this step. 
diff --git a/contrib/less/brac.c b/contrib/less/brac.c
index 53ada50aab56..58ecf172ae4e 100644
--- a/contrib/less/brac.c
+++ b/contrib/less/brac.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -84,7 +84,11 @@ match_brac(obrac, cbrac, forwdir, n)
 	while ((c = (*chget)()) != EOI)
 	{
 		if (c == obrac)
+		{
+			if (nest == INT_MAX)
+				break;
 			nest++;
+		}
 		else if (c == cbrac && --nest < 0)
 		{
 			/*
diff --git a/contrib/less/ch.c b/contrib/less/ch.c
index 379dd84c41b8..bfad09c719f6 100644
--- a/contrib/less/ch.c
+++ b/contrib/less/ch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -26,6 +26,10 @@ extern dev_t curr_dev;
 extern ino_t curr_ino;
 #endif
 
+#if HAVE_PROCFS
+#include <sys/statfs.h>
+#endif
+
 typedef POSITION BLOCKNUM;
 
 public int ignore_eoi;
@@ -725,7 +729,7 @@ ch_flush(VOID_PARAM)
 	ch_block = 0; /* ch_fpos / LBUFSIZE; */
 	ch_offset = 0; /* ch_fpos % LBUFSIZE; */
 
-#if 1
+#if HAVE_PROCFS
 	/*
 	 * This is a kludge to workaround a Linux kernel bug: files in
 	 * /proc have a size of 0 according to fstat() but have readable 
@@ -734,8 +738,15 @@ ch_flush(VOID_PARAM)
 	 */
 	if (ch_fsize == 0)
 	{
-		ch_fsize = NULL_POSITION;
-		ch_flags &= ~CH_CANSEEK;
+		struct statfs st;
+		if (fstatfs(ch_file, &st) == 0)
+		{
+			if (st.f_type == PROC_SUPER_MAGIC)
+			{
+				ch_fsize = NULL_POSITION;
+				ch_flags &= ~CH_CANSEEK;
+			}
+		}
 	}
 #endif
 
diff --git a/contrib/less/charset.c b/contrib/less/charset.c
index b37c8a29cbd9..5e9a2d6427b8 100644
--- a/contrib/less/charset.c
+++ b/contrib/less/charset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -445,7 +445,7 @@ prchar(c)
 	LWCHAR c;
 {
 	/* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */
-	static char buf[32];
+	static char buf[MAX_PRCHAR_LEN+1];
 
 	c &= 0377;
 	if ((c < 128 || !utf_mode) && !control_char(c))
@@ -480,7 +480,7 @@ prchar(c)
 prutfchar(ch)
 	LWCHAR ch;
 {
-	static char buf[32];
+	static char buf[MAX_PRCHAR_LEN+1];
 
 	if (ch == ESC)
 		strcpy(buf, "ESC");
@@ -805,18 +805,6 @@ is_ubin_char(ch)
 {
 	int ubin = is_in_table(ch, &ubin_table) ||
 	           (bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table));
-#if MSDOS_COMPILER==WIN32C
-	if (!ubin && utf_mode == 2 && ch < 0x10000)
-	{
-		/*
-		 * Consider it binary if it can't be converted.
-		 */
-		BOOL used_default = TRUE;
-		WideCharToMultiByte(GetConsoleOutputCP(), WC_NO_BEST_FIT_CHARS, (LPCWSTR) &ch, 1, NULL, 0, NULL, &used_default);
-		if (used_default)
-			ubin = 1;
-	}
-#endif
 	return ubin;
 }
 
diff --git a/contrib/less/charset.h b/contrib/less/charset.h
index 3e7ecf73db94..aa6273dfda6c 100644
--- a/contrib/less/charset.h
+++ b/contrib/less/charset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
diff --git a/contrib/less/cmd.h b/contrib/less/cmd.h
index c51f0bc5c4f3..b0f3fdb14b1e 100644
--- a/contrib/less/cmd.h
+++ b/contrib/less/cmd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -142,4 +142,5 @@
 #define SK_F1                  14
 #define SK_BACKTAB             15
 #define SK_CTL_BACKSPACE       16
+#define SK_BACKSPACE           17
 #define SK_CONTROL_K           40
diff --git a/contrib/less/cmdbuf.c b/contrib/less/cmdbuf.c
index dd135382aa11..5b5704602d8d 100644
--- a/contrib/less/cmdbuf.c
+++ b/contrib/less/cmdbuf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -24,6 +24,7 @@ extern int sc_width;
 extern int utf_mode;
 extern int no_hist_dups;
 extern int marks_modified;
+extern int secure;
 
 static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */
 static int cmd_col;              /* Current column of the cursor */
@@ -31,7 +32,7 @@ static int prompt_col;           /* Column of cursor just after prompt */
 static char *cp;                 /* Pointer into cmdbuf */
 static int cmd_offset;           /* Index into cmdbuf of first displayed char */
 static int literal;              /* Next input char should not be interpreted */
-static int updown_match = -1;    /* Prefix length in up/down movement */
+public int updown_match = -1;    /* Prefix length in up/down movement */
 
 #if TAB_COMPLETE_FILENAME
 static int cmd_complete LESSPARAMS((int action));
@@ -860,9 +861,10 @@ cmd_edit(c)
 		flags |= ECF_NOHISTORY;
 #endif
 #if TAB_COMPLETE_FILENAME
-	if (curr_mlist == ml_search)
+	if (curr_mlist == ml_search || curr_mlist == NULL)
 		/*
-		 * In a search command; don't accept file-completion cmds.
+		 * Don't accept file-completion cmds in contexts 
+		 * such as search pattern, digits, long option name, etc.
 		 */
 		flags |= ECF_NOCOMPLETE;
 #endif
@@ -1352,7 +1354,15 @@ cmd_int(frac)
 	int err;
 
 	for (p = cmdbuf;  *p >= '0' && *p <= '9';  p++)
-		n = (n * 10) + (*p - '0');
+	{
+		LINENUM nn = (n * 10) + (*p - '0');
+		if (nn < n)
+		{
+			error("Integer is too big", NULL_PARG);
+			return (0);
+		}
+		n = nn;
+	}
 	*frac = 0;
 	if (*p++ == '.')
 	{
@@ -1368,6 +1378,9 @@ cmd_int(frac)
 	public char *
 get_cmdbuf(VOID_PARAM)
 {
+	if (cmd_mbc_buf_index < cmd_mbc_buf_len)
+		/* Don't return buffer containing an incomplete multibyte char. */
+		return (NULL);
 	return (cmdbuf);
 }
 
@@ -1400,14 +1413,41 @@ mlist_size(ml)
 /*
  * Get the name of the history file.
  */
+	static char *
+histfile_find(must_exist)
+	int must_exist;
+{
+	char *home = lgetenv("HOME");
+	char *name = NULL;
+
+	/* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */
+#if OS2
+	if (isnullenv(home))
+		home = lgetenv("INIT");
+#endif
+	name = dirfile(lgetenv("XDG_STATE_HOME"), &LESSHISTFILE[1], must_exist);
+	if (name == NULL)
+	{
+		char *dir = dirfile(home, ".local/state", 1);
+		if (dir != NULL)
+		{
+			name = dirfile(dir, &LESSHISTFILE[1], must_exist);
+			free(dir);
+		}
+	}
+	if (name == NULL)
+		name = dirfile(lgetenv("XDG_DATA_HOME"), &LESSHISTFILE[1], must_exist);
+	if (name == NULL)
+		name = dirfile(home, LESSHISTFILE, must_exist);
+	return (name);
+}
+
 	static char *
 histfile_name(must_exist)
 	int must_exist;
 {
-	char *home;
-	char *xdg;
 	char *name;
-	
+
 	/* See if filename is explicitly specified by $LESSHISTFILE. */
 	name = lgetenv("LESSHISTFILE");
 	if (!isnullenv(name))
@@ -1422,25 +1462,14 @@ histfile_name(must_exist)
 	if (strcmp(LESSHISTFILE, "") == 0 || strcmp(LESSHISTFILE, "-") == 0)
 		return (NULL);
 
-	/* Try in $XDG_DATA_HOME first, then in $HOME. */
-	xdg = lgetenv("XDG_DATA_HOME");
-	home = lgetenv("HOME");
-#if OS2
-	if (isnullenv(home))
-		home = lgetenv("INIT");
-#endif
 	name = NULL;
 	if (!must_exist)
 	{
 	 	/* If we're writing the file and the file already exists, use it. */
-		name = dirfile(xdg, &LESSHISTFILE[1], 1);
-		if (name == NULL)
-			name = dirfile(home, LESSHISTFILE, 1);
+		name = histfile_find(1);
 	}
 	if (name == NULL)
-		name = dirfile(xdg, &LESSHISTFILE[1], must_exist);
-	if (name == NULL)
-		name = dirfile(home, LESSHISTFILE, must_exist);
+		name = histfile_find(must_exist);
 	return (name);
 }
 
@@ -1524,17 +1553,22 @@ read_cmdhist(action, uparam, skip_search, skip_shell)
 	int skip_search;
 	int skip_shell;
 {
+	if (secure)
+		return;
 	read_cmdhist2(action, uparam, skip_search, skip_shell);
 	(*action)(uparam, NULL, NULL); /* signal end of file */
 }
 
 	static void
-addhist_init(void *uparam, struct mlist *ml, char *string)
+addhist_init(uparam, ml, string)
+	void *uparam;
+	struct mlist *ml;
+	char constant *string;
 {
 	if (ml != NULL)
 		cmd_addhist(ml, string, 0);
 	else if (string != NULL)
-		restore_mark(string);
+		restore_mark((char*)string); /* stupid const cast */
 }
 #endif /* CMD_HISTORY */
 
@@ -1611,7 +1645,10 @@ struct save_ctx
  * created during this session.
  */
 	static void
-copy_hist(void *uparam, struct mlist *ml, char *string)
+copy_hist(uparam, ml, string)
+	void *uparam;
+	struct mlist *ml;
+	char constant *string;
 {
 	struct save_ctx *ctx = (struct save_ctx *) uparam;
 
@@ -1673,6 +1710,7 @@ make_file_private(f)
 /*
  * Does the history file need to be updated?
  */
+#if CMD_HISTORY
 	static int
 histfile_modified(VOID_PARAM)
 {
@@ -1682,12 +1720,11 @@ histfile_modified(VOID_PARAM)
 	if (mlist_shell.modified)
 		return 1;
 #endif
-#if CMD_HISTORY
 	if (marks_modified)
 		return 1;
-#endif
 	return 0;
 }
+#endif
 
 /*
  * Update the .lesshst file.
@@ -1705,7 +1742,7 @@ save_cmdhist(VOID_PARAM)
 	FILE *fout = NULL;
 	int histsize = 0;
 
-	if (!histfile_modified())
+	if (secure || !histfile_modified())
 		return;
 	histname = histfile_name(0);
 	if (histname == NULL)
diff --git a/contrib/less/command.c b/contrib/less/command.c
index 171788f2e750..8bd999e9f7a3 100644
--- a/contrib/less/command.c
+++ b/contrib/less/command.c
@@ -1,6 +1,6 @@
 /* $FreeBSD$ */
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -50,6 +50,9 @@ extern IFILE curr_ifile;
 extern void *ml_search;
 extern void *ml_examine;
 extern int wheel_lines;
+extern int header_lines;
+extern int def_search_type;
+extern int updown_match;
 #if SHELL_ESCAPE || PIPEC
 extern void *ml_shell;
 #endif
@@ -154,7 +157,7 @@ in_mca(VOID_PARAM)
  * Set up the display to start a new search command.
  */
 	static void
-mca_search(VOID_PARAM)
+mca_search1(VOID_PARAM)
 {
 #if HILITE_SEARCH
 	if (search_type & SRCH_FILTER)
@@ -189,6 +192,12 @@ mca_search(VOID_PARAM)
 	else
 		cmd_putstr("?");
 	forw_prompt = 0;
+}
+
+	static void
+mca_search(VOID_PARAM)
+{
+	mca_search1();
 	set_mlist(ml_search, 0);
 }
 
@@ -235,6 +244,8 @@ exec_mca(VOID_PARAM)
 
 	cmd_exec();
 	cbuf = get_cmdbuf();
+	if (cbuf == NULL)
+		return;
 
 	switch (mca)
 	{
@@ -342,6 +353,7 @@ is_newline_char(c)
 mca_opt_first_char(c)
 	int c;
 {
+	int no_prompt = (optflag & OPT_NO_PROMPT);
 	int flag = (optflag & ~OPT_NO_PROMPT);
 	if (flag == OPT_NO_TOGGLE)
 	{
@@ -359,14 +371,14 @@ mca_opt_first_char(c)
 		{
 		case '+':
 			/* "-+" = UNSET. */
-			optflag = (flag == OPT_UNSET) ?
-				OPT_TOGGLE : OPT_UNSET;
+			optflag = no_prompt | ((flag == OPT_UNSET) ?
+				OPT_TOGGLE : OPT_UNSET);
 			mca_opt_toggle();
 			return (MCA_MORE);
 		case '!':
 			/* "-!" = SET */
-			optflag = (flag == OPT_SET) ?
-				OPT_TOGGLE : OPT_SET;
+			optflag = no_prompt | ((flag == OPT_SET) ?
+				OPT_TOGGLE : OPT_SET);
 			mca_opt_toggle();
 			return (MCA_MORE);
 		case CONTROL('P'):
@@ -415,6 +427,8 @@ mca_opt_nonfirst_char(c)
 	if (cmd_char(c) == CC_QUIT)
 		return (MCA_DONE);
 	p = get_cmdbuf();
+	if (p == NULL)
+		return (MCA_MORE);
 	opt_lower = ASCII_IS_LOWER(p[0]);
 	err = 0;
 	curropt = findopt_name(&p, &oname, &err);
@@ -465,11 +479,13 @@ mca_opt_char(c)
 	if (optgetname)
 	{
 		/* We're getting a long option name.  */
-		if (!is_newline_char(c))
+		if (!is_newline_char(c) && c != '=')
 			return (mca_opt_nonfirst_char(c));
 		if (curropt == NULL)
 		{
 			parg.p_string = get_cmdbuf();
+			if (parg.p_string == NULL)
+				return (MCA_MORE);
 			error("There is no --%s option", &parg);
 			return (MCA_DONE);
 		}
@@ -509,6 +525,19 @@ mca_opt_char(c)
 	return (MCA_MORE);
 }
 
+/*
+ * Normalize search type.
+ */
+	public int
+norm_search_type(st)
+	int st;
+{
+	/* WRAP and PAST_EOF are mutually exclusive. */
+	if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP))
+		st ^= SRCH_PAST_EOF;
+	return st;
+}
+
 /*
  * Handle a char of a search command.
  */
@@ -563,8 +592,7 @@ mca_search_char(c)
 
 	if (flag != 0)
 	{
-		/* Toggle flag, but keep PAST_EOF and WRAP mutually exclusive. */
-		search_type ^= flag | (search_type & (SRCH_PAST_EOF|SRCH_WRAP));
+		search_type = norm_search_type(search_type ^ flag);
 		mca_search();
 		return (MCA_MORE);
 	}
@@ -686,6 +714,14 @@ mca_char(c)
 			/* Incremental search: do a search after every input char. */
 			int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP));
 			char *pattern = get_cmdbuf();
+			if (pattern == NULL)
+				return (MCA_MORE);
+			/*
+			 * Must save updown_match because mca_search
+			 * reinits it. That breaks history scrolling.
+			 * {{ This is ugly. mca_search probably shouldn't call set_mlist. }}
+			 */
+			int save_updown_match = updown_match;
 			cmd_exec();
 			if (*pattern == '\0')
 			{
@@ -698,7 +734,8 @@ mca_char(c)
 					undo_search(1);
 			}
 			/* Redraw the search prompt and search string. */
-			mca_search();
+			mca_search1();
+			updown_match = save_updown_match;
 			cmd_repaint(NULL);
 		}
 		break;
@@ -806,7 +843,7 @@ prompt(VOID_PARAM)
 	if (!(ch_getflags() & CH_HELPFILE))
 	{
 		WCHAR w[MAX_PATH+16];
-		p = pr_expand("Less?f - %f.", 0);
+		p = pr_expand("Less?f - %f.");
 		MultiByteToWideChar(CP_ACP, 0, p, -1, w, sizeof(w)/sizeof(*w));
 		SetConsoleTitleW(w);
 	}
@@ -849,9 +886,8 @@ prompt(VOID_PARAM)
 		                    0, w, -1, a, sizeof(a), NULL, NULL);
 		p = a;
 #endif
-		at_enter(AT_STANDOUT|AT_COLOR_PROMPT);
-		putstr(p);
-		at_exit();
+		load_line(p);
+		put_line();
 	}
 	clear_eol();
 }
@@ -928,8 +964,8 @@ getccu(VOID_PARAM)
  */
 	static LWCHAR
 getcc_repl(orig, repl, gr_getc, gr_ungetc)
-	char const* orig;
-	char const* repl;
+	char constant* orig;
+	char constant* repl;
 	LWCHAR (*gr_getc)(VOID_PARAM);
 	void (*gr_ungetc)(LWCHAR);
 {
@@ -1286,6 +1322,8 @@ commands(VOID_PARAM)
 				if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0)
 					continue;
 				cbuf = get_cmdbuf();
+				if (cbuf == NULL)
+					continue;
 			} else
 			{
 				/*
@@ -1609,7 +1647,7 @@ commands(VOID_PARAM)
 			 * Search forward for a pattern.
 			 * Get the first char of the pattern.
 			 */
-			search_type = SRCH_FORW;
+			search_type = SRCH_FORW | def_search_type;
 			if (number <= 0)
 				number = 1;
 			mca_search();
@@ -1621,7 +1659,7 @@ commands(VOID_PARAM)
 			 * Search backward for a pattern.
 			 * Get the first char of the pattern.
 			 */
-			search_type = SRCH_BACK;
+			search_type = SRCH_BACK | def_search_type;
 			if (number <= 0)
 				number = 1;
 			mca_search();
@@ -1741,7 +1779,7 @@ commands(VOID_PARAM)
 				 */
 				make_display();
 				cmd_exec();
-				lsystem(pr_expand(editproto, 0), (char*)NULL);
+				lsystem(pr_expand(editproto), (char*)NULL);
 				break;
 			}
 #endif
diff --git a/contrib/less/compose.uni b/contrib/less/compose.uni
index bbf4b20387fc..cc7ddcf02bb9 100644
--- a/contrib/less/compose.uni
+++ b/contrib/less/compose.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue May 19 14:47:34 PDT 2020 */
+/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:16 PDT 2022 */
 	{ 0x0300, 0x036f }, /* Mn */
 	{ 0x0483, 0x0487 }, /* Mn */
 	{ 0x0488, 0x0489 }, /* Me */
@@ -24,7 +24,8 @@
 	{ 0x0825, 0x0827 }, /* Mn */
 	{ 0x0829, 0x082d }, /* Mn */
 	{ 0x0859, 0x085b }, /* Mn */
-	{ 0x08d3, 0x08e1 }, /* Mn */
+	{ 0x0898, 0x089f }, /* Mn */
+	{ 0x08ca, 0x08e1 }, /* Mn */
 	{ 0x08e3, 0x0902 }, /* Mn */
 	{ 0x093a, 0x093a }, /* Mn */
 	{ 0x093c, 0x093c }, /* Mn */
@@ -65,6 +66,7 @@
 	{ 0x0bcd, 0x0bcd }, /* Mn */
 	{ 0x0c00, 0x0c00 }, /* Mn */
 	{ 0x0c04, 0x0c04 }, /* Mn */
+	{ 0x0c3c, 0x0c3c }, /* Mn */
 	{ 0x0c3e, 0x0c40 }, /* Mn */
 	{ 0x0c46, 0x0c48 }, /* Mn */
 	{ 0x0c4a, 0x0c4d }, /* Mn */
@@ -115,7 +117,7 @@
 	{ 0x1160, 0x11ff }, /* Mn */
 	{ 0x135d, 0x135f }, /* Mn */
 	{ 0x1712, 0x1714 }, /* Mn */
-	{ 0x1732, 0x1734 }, /* Mn */
+	{ 0x1732, 0x1733 }, /* Mn */
 	{ 0x1752, 0x1753 }, /* Mn */
 	{ 0x1772, 0x1773 }, /* Mn */
 	{ 0x17b4, 0x17b5 }, /* Mn */
@@ -124,6 +126,7 @@
 	{ 0x17c9, 0x17d3 }, /* Mn */
 	{ 0x17dd, 0x17dd }, /* Mn */
 	{ 0x180b, 0x180d }, /* Mn */
+	{ 0x180f, 0x180f }, /* Mn */
 	{ 0x1885, 0x1886 }, /* Mn */
 	{ 0x18a9, 0x18a9 }, /* Mn */
 	{ 0x1920, 0x1922 }, /* Mn */
@@ -141,7 +144,7 @@
 	{ 0x1a7f, 0x1a7f }, /* Mn */
 	{ 0x1ab0, 0x1abd }, /* Mn */
 	{ 0x1abe, 0x1abe }, /* Me */
-	{ 0x1abf, 0x1ac0 }, /* Mn */
+	{ 0x1abf, 0x1ace }, /* Mn */
 	{ 0x1b00, 0x1b03 }, /* Mn */
 	{ 0x1b34, 0x1b34 }, /* Mn */
 	{ 0x1b36, 0x1b3a }, /* Mn */
@@ -164,8 +167,7 @@
 	{ 0x1ced, 0x1ced }, /* Mn */
 	{ 0x1cf4, 0x1cf4 }, /* Mn */
 	{ 0x1cf8, 0x1cf9 }, /* Mn */
-	{ 0x1dc0, 0x1df9 }, /* Mn */
-	{ 0x1dfb, 0x1dff }, /* Mn */
+	{ 0x1dc0, 0x1dff }, /* Mn */
 	{ 0x20d0, 0x20dc }, /* Mn */
 	{ 0x20dd, 0x20e0 }, /* Me */
 	{ 0x20e1, 0x20e1 }, /* Mn */
@@ -229,11 +231,15 @@
 	{ 0x10d24, 0x10d27 }, /* Mn */
 	{ 0x10eab, 0x10eac }, /* Mn */
 	{ 0x10f46, 0x10f50 }, /* Mn */
+	{ 0x10f82, 0x10f85 }, /* Mn */
 	{ 0x11001, 0x11001 }, /* Mn */
 	{ 0x11038, 0x11046 }, /* Mn */
+	{ 0x11070, 0x11070 }, /* Mn */
+	{ 0x11073, 0x11074 }, /* Mn */
 	{ 0x1107f, 0x11081 }, /* Mn */
 	{ 0x110b3, 0x110b6 }, /* Mn */
 	{ 0x110b9, 0x110ba }, /* Mn */
+	{ 0x110c2, 0x110c2 }, /* Mn */
 	{ 0x11100, 0x11102 }, /* Mn */
 	{ 0x11127, 0x1112b }, /* Mn */
 	{ 0x1112d, 0x11134 }, /* Mn */
@@ -313,6 +319,8 @@
 	{ 0x16f8f, 0x16f92 }, /* Mn */
 	{ 0x16fe4, 0x16fe4 }, /* Mn */
 	{ 0x1bc9d, 0x1bc9e }, /* Mn */
+	{ 0x1cf00, 0x1cf2d }, /* Mn */
+	{ 0x1cf30, 0x1cf46 }, /* Mn */
 	{ 0x1d167, 0x1d169 }, /* Mn */
 	{ 0x1d17b, 0x1d182 }, /* Mn */
 	{ 0x1d185, 0x1d18b }, /* Mn */
diff --git a/contrib/less/cvt.c b/contrib/less/cvt.c
index 9cf44b894e7d..bb4649264f12 100644
--- a/contrib/less/cvt.c
+++ b/contrib/less/cvt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
diff --git a/contrib/less/decode.c b/contrib/less/decode.c
index 7e9b167bc786..0444cab399c9 100644
--- a/contrib/less/decode.c
+++ b/contrib/less/decode.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -206,7 +206,7 @@ static unsigned char edittable[] =
 	ESC,SK(SK_DELETE),0,            EC_W_DELETE,    /* ESC DELETE */
 	SK(SK_CTL_DELETE),0,            EC_W_DELETE,    /* CTRL-DELETE */
 	SK(SK_CTL_BACKSPACE),0,         EC_W_BACKSPACE, /* CTRL-BACKSPACE */
-	ESC,'\b',0,                     EC_W_BACKSPACE, /* ESC BACKSPACE */
+	ESC,SK(SK_BACKSPACE),0,         EC_W_BACKSPACE, /* ESC BACKSPACE */
 	ESC,'0',0,                      EC_HOME,        /* ESC 0 */
 	SK(SK_HOME),0,                  EC_HOME,        /* HOME */
 	ESC,'$',0,                      EC_END,         /* ESC $ */
@@ -268,7 +268,7 @@ expand_special_keys(table, len)
 			}
 			/*
 			 * After SK_SPECIAL_KEY, next byte is the type
-			 * of special key (one of the SK_* contants),
+			 * of special key (one of the SK_* constants),
 			 * and the byte after that is the number of bytes,
 			 * N, reserved by the abbreviation (including the
 			 * SK_SPECIAL_KEY and key type bytes).
@@ -785,6 +785,7 @@ new_lesskey(buf, len, sysvar)
 	int sysvar;
 {
 	char *p;
+	char *end;
 	int c;
 	int n;
 
@@ -797,6 +798,7 @@ new_lesskey(buf, len, sysvar)
 	    buf[len-1] != C2_END_LESSKEY_MAGIC)
 		return (-1);
 	p = buf + 4;
+	end = buf + len;
 	for (;;)
 	{
 		c = *p++;
@@ -804,16 +806,22 @@ new_lesskey(buf, len, sysvar)
 		{
 		case CMD_SECTION:
 			n = gint(&p);
+			if (n < 0 || p+n >= end)
+				return (-1);
 			add_fcmd_table(p, n);
 			p += n;
 			break;
 		case EDIT_SECTION:
 			n = gint(&p);
+			if (n < 0 || p+n >= end)
+				return (-1);
 			add_ecmd_table(p, n);
 			p += n;
 			break;
 		case VAR_SECTION:
 			n = gint(&p);
+			if (n < 0 || p+n >= end)
+				return (-1);
 			add_var_table((sysvar) ? 
 				&list_sysvar_tables : &list_var_tables, p, n);
 			p += n;
@@ -891,7 +899,8 @@ lesskey(filename, sysvar)
 	 * Figure out if this is an old-style (before version 241)
 	 * or new-style lesskey file format.
 	 */
-	if (buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
+	if (len < 4 || 
+	    buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
 	    buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC)
 		return (old_lesskey(buf, (int)len));
 	return (new_lesskey(buf, (int)len, sysvar));
@@ -943,9 +952,20 @@ add_hometable(call_lesskey, envname, def_filename, sysvar)
 		filename = save(def_filename);
 	else /* def_filename is just basename */
 	{
+		/* Remove first char (normally a dot) unless stored in $HOME. */
 		char *xdg = lgetenv("XDG_CONFIG_HOME");
 		if (!isnullenv(xdg))
-			filename = dirfile(xdg, def_filename+1, 1);
+			filename = dirfile(xdg, &def_filename[1], 1);
+		if (filename == NULL)
+		{
+			char *home = lgetenv("HOME");
+			if (!isnullenv(home))
+			{
+				char *cfg_dir = dirfile(home, ".config", 0);
+				filename = dirfile(cfg_dir, &def_filename[1], 1);
+				free(cfg_dir);
+			}
+		}
 		if (filename == NULL)
 			filename = homefile(def_filename);
 	}
diff --git a/contrib/less/edit.c b/contrib/less/edit.c
index 529ed75b0afe..151ac744f7b5 100644
--- a/contrib/less/edit.c
*** 3813 LINES SKIPPED ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202209200152.28K1q6a9007430>