|
From: Ethan A M. <me...@uw...> - 2026-07-18 07:05:18
|
On Thu, Jul 16, 2026 at 9:47 AM Juhász Péter <pet...@gm...> wrote: > > > executive summary: > the canonical form of the bind command (e.g. `bind a "replot"`) does > not work, probably since 2024, because of changeset 96d580c508. > Yes. My fault. Fixed now. Thanks for the report. So here's the story. I regularly run the full set of demos with saved output so that I can compare the plots produced before/after any code changes. The tests can be run under valgrind or asan to detect memory access violations. To the extent that the demos actually exercise all program options and the resulting code paths, it does a reasonable job of finding parsing errors, run-time errors, memory leaks, and so on in addition to detecting incorrectly generated plots. Unfortunately these tests do not exercise all terminal-specific code, and do not test mousing or other interactive use of the program. So they did not, and could not, catch this breakage in the "bind" command. If anyone has ideas of how to increase the coverage of automated testing, please speak up. It would also be helpful if you know of any program options or plot modes that are not part of the demo collection, and hence not tested. - Ethan > explanation: > Gnuplot is one of the few programs I still compile from source, > recompiling rarely, usually only when I change computers or upgrade the > OS. That's why I only noticed now that a company-internal analysis > script that relies heavily on `bind` stopped working after recompiling > the current gnuplot source. > > The simplest form of `bind`, e.g. `bind a "replot"`, as given in the > manual, does not do anything, it just fails silently. > > I believe the breakage was introduced in commit 96d580c508, > specifically this bit: > > @ -1037,8 +1037,7 @@ bind_command() > char *first = gp_input_line + token[c_token].start_index; > int size = strcspn(first, " \";"); > lhs = gp_alloc(size + 1, "bind_command->lhs"); > - strncpy(lhs, first, size); > - lhs[size] = '\0'; > + safe_strncpy(lhs, first, size); > FPRINTF((stderr,"Got bind unquoted lhs = \"%s\"\n",lhs)); > while (gp_input_line + token[c_token].start_index < first+size) > c_token++; > > `safe_strncpy` is aliased to `strlcpy`, if available, and I seem to > have it, but in any case, this is not an equivalent change. > > In the case of a naked single-character first argument to bind, size > will be 1 in the code above. `strlcpy` copies at most `size` (so, 1) > bytes, and sets the last (that is, the only) byte to null. > > Then the code that wants to set up the binding receives an empty > string, which causes it to silently fail. > > This incorrect behavior can be also seen with the command `bind RR > "replot"`, which is nonsensical and should be an error, but instead it > sets up the binding for "R". > > Luckily, the quoted case `bind "R" "replot"` still works. > > There may be other instances of this incorrect usage of safe_strncpy, I > haven't checked. > > best regards, > > Peter Juhasz > > > _______________________________________________ > gnuplot-beta mailing list > gnu...@li... > Membership management via: > https://urldefense.com/v3/__https://lists.sourceforge.net/lists/listinfo/gnuplot-beta__;!!K-Hz7m0Vt54!hwk5Sr7cG1SlpX05GVACsAMQf-E35prPcaVkLTXV_8BuQRntHCZc_iqZwwDXW9GpogtRy8M-YMpd9o-wp5MdDT0$ > -- Ethan A Merritt Department of Biochemistry University of Washington, Seattle |