>Synopsis: mg editor: endless loop using replace-regexp >Category: system >Environment: System : OpenBSD 7.4 Details : OpenBSD 7.4 (GENERIC.MP) #2: Fri Dec 8 15:39:04 MST 2023 r...@syspatch-74-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
Architecture: OpenBSD.amd64 Machine : amd64 >Description: The command 'regexp-replace "^.*$" ""' enters an endless loop (until memory exhausted). This behaviour also applies to query-replace-regexp with the "!" option. This is due to a change I suggested to re_forwsrch, that is, not moving dot when the line is empty (re_search.c 1.35). The reason for this change was to ensure the replacement took effect on the starting line of a replace-regexp, even if the line was empty. >How-To-Repeat: As above. >Fix: Here's an alternative method for achieving this end, without the unpleasant consquence. It's rather more intrusive than I'd like. --- re_search_orig.c 2024-03-02 13:00:43.734949005 +0000 +++ re_search.c 2024-03-04 14:33:09.659288168 +0000 @@ -34,12 +34,15 @@ #define RE_NMATCH 10 /* max number of matches */ #define REPLEN 256 /* max length of replacement string */ +#define MOVEDOT 1 /* for use with re_forwsrch */ +#define NO_MOVEDOT 0 + char re_pat[NPAT]; /* regex pattern */ int re_srch_lastdir = SRCH_NOPR; /* last search flags */ int casefoldsearch = TRUE; /* does search ignore case? */ static int re_doreplace(RSIZE, char *); -static int re_forwsrch(void); +static int re_forwsrch(int); static int re_backsrch(void); static int re_readpattern(char *); static int killmatches(int); @@ -58,7 +61,7 @@ if ((s = re_readpattern("RE Search")) != TRUE) return (s); - if (re_forwsrch() == FALSE) { + if (re_forwsrch(MOVEDOT) == FALSE) { dobeep(); ewprintf("Search failed: \"%s\"", re_pat); return (FALSE); @@ -107,7 +110,7 @@ return (FALSE); } if (re_srch_lastdir == SRCH_FORW) { - if (re_forwsrch() == FALSE) { + if (re_forwsrch(MOVEDOT) == FALSE) { dobeep(); ewprintf("Search failed: \"%s\"", re_pat); return (FALSE); @@ -138,6 +141,8 @@ int rcnt = 0; /* replacements made so far */ int plen, s; /* length of found string */ char news[NPAT]; /* replacement string */ + int movedot = NO_MOVEDOT; /* no dot move on first call to */ + /* forwsrch */ if ((s = re_readpattern("RE Query replace")) != TRUE) return (s); @@ -151,7 +156,8 @@ * or not. The "!" case makes the check always true, so it gets put * into a tighter loop for efficiency. */ - while (re_forwsrch() == TRUE) { + while (re_forwsrch(movedot) == TRUE) { + movedot = MOVEDOT; retry: update(CMODE); switch (getkey(FALSE)) { @@ -181,7 +187,7 @@ if (re_doreplace((RSIZE)plen, news) == FALSE) return (FALSE); rcnt++; - } while (re_forwsrch() == TRUE); + } while (re_forwsrch(MOVEDOT) == TRUE); goto stopsearch; case CCHR('?'): /* To not replace */ @@ -220,7 +226,7 @@ EFNUL | EFNEW | EFCR, re_pat) == NULL) return (ABORT); - while (re_forwsrch() == TRUE) { + while (re_forwsrch(rcnt) == TRUE) { plen = regex_match[0].rm_eo - regex_match[0].rm_so; if (re_doreplace((RSIZE)plen, news) == FALSE) return (FALSE); @@ -327,10 +333,14 @@ * This routine does the real work of a forward search. The pattern is * sitting in the external variable "pat". If found, dot is updated, the * window system is notified of the change, and TRUE is returned. If the - * string isn't found, FALSE is returned. + * string isn't found, FALSE is returned. + * + * If movedot is non-zero, dot at end of line is shifted to next line. + * If zero, dot is left unchanged, which allows matching anchors in + * an empty starting line. */ static int -re_forwsrch(void) +re_forwsrch(int movedot) { int re_flags, tbo, tdotline, error; struct line *clp; @@ -339,13 +349,12 @@ tbo = curwp->w_doto; tdotline = curwp->w_dotline; - if (tbo == clp->l_used) + if (tbo == clp->l_used && movedot) /* - * Don't start matching past end of line -- must move to - * beginning of next line, unless line is empty or at - * end of file. + * Don't start matching past end of line if movedot is true + * - must move to beginning of next line, unless at end of file. */ - if (clp != curbp->b_headp && llength(clp) != 0) { + if (clp != curbp->b_headp) { clp = lforw(clp); tdotline++; tbo = 0; dmesg: OpenBSD 7.4 (GENERIC.MP) #2: Fri Dec 8 15:39:04 MST 2023 r...@syspatch-74-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP real mem = 8523141120 (8128MB) avail mem = 8245096448 (7863MB) random: good seed from bootblocks mpath0 at root scsibus0 at mpath0: 256 targets mainbus0 at root bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xf6540 (57 entries) bios0: vendor Dell Inc. version "A19" date 12/21/2009 bios0: Dell Inc. Latitude E6500 acpi0 at bios0: ACPI 4.0 acpi0: sleep states S0 S3 S4 S5 acpi0: tables DSDT FACP HPET DMAR APIC ASF! MCFG TCPA SLIC SSDT acpi0: wakeup devices PCI0(S4) PCIE(S4) USB1(S0) USB2(S0) USB3(S0) USB4(S0) USB5(S0) USB6(S0) EHC2(S0) EHCI(S0) AZAL(S3) RP01(S4) RP02(S4) RP03(S4) RP04(S3) RP05(S3) [...] acpitimer0 at acpi0: 3579545 Hz, 24 bits acpihpet0 at acpi0: 14318179 Hz acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat cpu0 at mainbus0: apid 0 (boot processor) cpu0: Intel(R) Core(TM)2 Duo CPU P8800 @ 2.66GHz, 2660.05 MHz, 06-17-0a, patch 00000a0b cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,XSAVE,NXE,LONG,LAHF,PERF,SENSOR,MELTDOWN cpu0: 32KB 64b/line 8-way D-cache, 32KB 64b/line 8-way I-cache, 3MB 64b/line 12-way L2 cache cpu0: smt 0, core 0, package 0 mtrr: Pentium Pro MTRR support, 7 var ranges, 88 fixed ranges cpu0: apic clock running at 266MHz cpu0: mwait min=64, max=64, C-substates=0.2.2.2.2.1.3, IBE cpu1 at mainbus0: apid 1 (application processor) cpu1: Intel(R) Core(TM)2 Duo CPU P8800 @ 2.66GHz, 2660.05 MHz, 06-17-0a, patch 00000a0b cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,XSAVE,NXE,LONG,LAHF,PERF,SENSOR,MELTDOWN cpu1: 32KB 64b/line 8-way D-cache, 32KB 64b/line 8-way I-cache, 3MB 64b/line 12-way L2 cache cpu1: smt 0, core 1, package 0 ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 24 pins, remapped acpimcfg0 at acpi0 acpimcfg0: addr 0xf8000000, bus 0-63 acpimcfg0: addr 0x0, bus 0-0 acpiprt0 at acpi0: bus 0 (PCI0) acpiprt1 at acpi0: bus 3 (PCIE) acpiprt2 at acpi0: bus -1 (AGP_) acpiprt3 at acpi0: bus 11 (RP01) acpiprt4 at acpi0: bus 12 (RP02) acpiprt5 at acpi0: bus 13 (RP03) acpiprt6 at acpi0: bus 14 (RP04) acpiprt7 at acpi0: bus -1 (RP05) acpiprt8 at acpi0: bus -1 (RP06) acpiec0 at acpi0 acpipci0 at acpi0 PCI0 acpicmos0 at acpi0 acpibtn0 at acpi0: LID_(wakeup) acpibtn1 at acpi0: PBTN(wakeup) acpibtn2 at acpi0: SBTN acpiac0 at acpi0: AC unit online acpibat0 at acpi0: BAT0 model "DELL C207203" serial 5003 type LION oem "Samsung SDI" acpibat1 at acpi0: BAT1 not present "*pnp0c14" at acpi0 not configured acpicpu0 at acpi0: !C3(100@162 mwait.3@0x50), !C2(500@1 mwait.1@0x10), C1(1000@1 mwait.1), PSS acpicpu1 at acpi0: !C3(100@162 mwait.3@0x50), !C2(500@1 mwait.1@0x10), C1(1000@1 mwait.1), PSS acpitz0 at acpi0: critical temperature is 107 degC acpivideo0 at acpi0: VID_ acpivideo1 at acpi0: VID_ acpivout0 at acpivideo1: LCD_ acpivideo2 at acpi0: VID2 cpu0: Enhanced SpeedStep 2660 MHz: speeds: 2668, 2667, 2134, 1600, 800 MHz pci0 at mainbus0 bus 0 pchb0 at pci0 dev 0 function 0 "Intel GM45 Host" rev 0x07 inteldrm0 at pci0 dev 2 function 0 "Intel GM45 Video" rev 0x07 drm0 at inteldrm0 intagp0 at inteldrm0 agp0 at intagp0: aperture at 0xe0000000, size 0x10000000 inteldrm0: apic 2 int 16, GM45, gen 4 "Intel GM45 Video" rev 0x07 at pci0 dev 2 function 1 not configured em0 at pci0 dev 25 function 0 "Intel ICH9 IGP M AMT" rev 0x03: msi, address 00:26:b9:bf:2e:70 uhci0 at pci0 dev 26 function 0 "Intel 82801I USB" rev 0x03: apic 2 int 20 uhci1 at pci0 dev 26 function 1 "Intel 82801I USB" rev 0x03: apic 2 int 21 uhci2 at pci0 dev 26 function 2 "Intel 82801I USB" rev 0x03: apic 2 int 22 ehci0 at pci0 dev 26 function 7 "Intel 82801I USB" rev 0x03: apic 2 int 22 usb0 at ehci0: USB revision 2.0 uhub0 at usb0 configuration 1 interface 0 "Intel EHCI root hub" rev 2.00/1.00 addr 1 azalia0 at pci0 dev 27 function 0 "Intel 82801I HD Audio" rev 0x03: msi azalia0: codecs: IDT 92HD71B7, Intel/0x2802, using IDT 92HD71B7 audio0 at azalia0 ppb0 at pci0 dev 28 function 0 "Intel 82801I PCIE" rev 0x03: msi pci1 at ppb0 bus 11 ppb1 at pci0 dev 28 function 1 "Intel 82801I PCIE" rev 0x03: msi pci2 at ppb1 bus 12 "Broadcom BCM4315" rev 0x01 at pci2 dev 0 function 0 not configured ppb2 at pci0 dev 28 function 2 "Intel 82801I PCIE" rev 0x03: msi pci3 at ppb2 bus 13 ppb3 at pci0 dev 28 function 3 "Intel 82801I PCIE" rev 0x03: msi pci4 at ppb3 bus 14 uhci3 at pci0 dev 29 function 0 "Intel 82801I USB" rev 0x03: apic 2 int 20 uhci4 at pci0 dev 29 function 1 "Intel 82801I USB" rev 0x03: apic 2 int 21 uhci5 at pci0 dev 29 function 2 "Intel 82801I USB" rev 0x03: apic 2 int 22 ehci1 at pci0 dev 29 function 7 "Intel 82801I USB" rev 0x03: apic 2 int 20 usb1 at ehci1: USB revision 2.0 uhub1 at usb1 configuration 1 interface 0 "Intel EHCI root hub" rev 2.00/1.00 addr 1 ppb4 at pci0 dev 30 function 0 "Intel 82801BAM Hub-to-PCI" rev 0x93 pci5 at ppb4 bus 3 cbb0 at pci5 dev 1 function 0 "Ricoh 5C476 CardBus" rev 0xba: apic 2 int 19 "Ricoh 5C832 Firewire" rev 0x04 at pci5 dev 1 function 1 not configured sdhc0 at pci5 dev 1 function 2 "Ricoh 5C822 SD/MMC" rev 0x21: apic 2 int 18 sdhc0: SDHC 1.00, 33 MHz base clock sdmmc0 at sdhc0: 4-bit, sd high-speed, mmc high-speed "Ricoh 5C843 MMC" rev 0x11 at pci5 dev 1 function 3 not configured cardslot0 at cbb0 slot 0 flags 0 cardbus0 at cardslot0: bus 4 device 0 cacheline 0x10, lattimer 0x20 pcmcia0 at cardslot0 pcib0 at pci0 dev 31 function 0 "Intel 82801IEM LPC" rev 0x03 ahci0 at pci0 dev 31 function 2 "Intel 82801I AHCI" rev 0x03: msi, AHCI 1.2 ahci0: port 0: 3.0Gb/s ahci0: port 1: 1.5Gb/s scsibus1 at ahci0: 32 targets sd0 at scsibus1 targ 0 lun 0: <ATA, KINGSTON SV300S3, 603A> naa.50026b775605cd58 sd0: 228936MB, 512 bytes/sector, 468862128 sectors, thin cd0 at scsibus1 targ 1 lun 0: <TSSTcorp, DVD+-RW TS-U633F, D500> removable ichiic0 at pci0 dev 31 function 3 "Intel 82801I SMBus" rev 0x03: apic 2 int 17 iic0 at ichiic0 spdmem0 at iic0 addr 0x50: 4GB DDR2 SDRAM non-parity PC2-6400CL6 SO-DIMM spdmem1 at iic0 addr 0x52: 4GB DDR2 SDRAM non-parity PC2-6400CL6 SO-DIMM usb2 at uhci0: USB revision 1.0 uhub2 at usb2 configuration 1 interface 0 "Intel UHCI root hub" rev 1.00/1.00 addr 1 usb3 at uhci1: USB revision 1.0 uhub3 at usb3 configuration 1 interface 0 "Intel UHCI root hub" rev 1.00/1.00 addr 1 usb4 at uhci2: USB revision 1.0 uhub4 at usb4 configuration 1 interface 0 "Intel UHCI root hub" rev 1.00/1.00 addr 1 usb5 at uhci3: USB revision 1.0 uhub5 at usb5 configuration 1 interface 0 "Intel UHCI root hub" rev 1.00/1.00 addr 1 usb6 at uhci4: USB revision 1.0 uhub6 at usb6 configuration 1 interface 0 "Intel UHCI root hub" rev 1.00/1.00 addr 1 usb7 at uhci5: USB revision 1.0 uhub7 at usb7 configuration 1 interface 0 "Intel UHCI root hub" rev 1.00/1.00 addr 1 isa0 at pcib0 isadma0 at isa0 pckbc0 at isa0 port 0x60/5 irq 1 irq 12 pckbd0 at pckbc0 (kbd slot) wskbd0 at pckbd0: console keyboard pms0 at pckbc0 (aux slot) wsmouse0 at pms0 mux 0 pms0: ALPS Dualpoint, version 0x6222 wsmouse1 at pms0 mux 0 pcppi0 at isa0 port 0x61 spkr0 at pcppi0 vmm0 at mainbus0: unknown ugen0 at uhub4 port 1 "Broadcom Corp 5880" rev 1.10/1.01 addr 2 uhidev0 at uhub6 port 2 configuration 1 interface 0 "vendor 0x13ba Barcode Reader" rev 1.10/0.01 addr 2 uhidev0: iclass 3/1 ukbd0 at uhidev0: 8 variable keys, 6 key codes wskbd1 at ukbd0 mux 1 uhidev1 at uhub6 port 2 configuration 1 interface 1 "vendor 0x13ba Barcode Reader" rev 1.10/0.01 addr 2 uhidev1: iclass 3/1, 3 report ids ums0 at uhidev1 reportid 1: 5 buttons, Z dir wsmouse2 at ums0 mux 0 uhid0 at uhidev1 reportid 2: input=1, output=0, feature=0 ucc0 at uhidev1 reportid 3: 573 usages, 20 keys, array wskbd2 at ucc0 mux 1 vscsi0 at root scsibus2 at vscsi0: 256 targets softraid0 at root scsibus3 at softraid0: 256 targets root on sd0a (660795fa2a3e9604.a) swap on sd0b dump on sd0b inteldrm0: 1024x768, 32bpp wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0 wskbd1: connecting to wsdisplay0 wskbd2: connecting to wsdisplay0 wsdisplay0: screen 1-5 added (std, vt100 emulation) usbdevs: Controller /dev/usb0: addr 01: 8086:0000 Intel, EHCI root hub high speed, self powered, config 1, rev 1.00 driver: uhub0 Controller /dev/usb1: addr 01: 8086:0000 Intel, EHCI root hub high speed, self powered, config 1, rev 1.00 driver: uhub1 Controller /dev/usb2: addr 01: 8086:0000 Intel, UHCI root hub full speed, self powered, config 1, rev 1.00 driver: uhub2 Controller /dev/usb3: addr 01: 8086:0000 Intel, UHCI root hub full speed, self powered, config 1, rev 1.00 driver: uhub3 Controller /dev/usb4: addr 01: 8086:0000 Intel, UHCI root hub full speed, self powered, config 1, rev 1.00 driver: uhub4 addr 02: 0a5c:5800 Broadcom Corp, 5880 full speed, power 100 mA, unconfigured, rev 1.01, iSerial 0123456789ABCD driver: ugen0 Controller /dev/usb5: addr 01: 8086:0000 Intel, UHCI root hub full speed, self powered, config 1, rev 1.00 driver: uhub5 Controller /dev/usb6: addr 01: 8086:0000 Intel, UHCI root hub full speed, self powered, config 1, rev 1.00 driver: uhub6 addr 02: 13ba:0018 vendor 0x13ba, Barcode Reader low speed, power 400 mA, config 1, rev 0.01 driver: uhidev0 driver: uhidev1 Controller /dev/usb7: addr 01: 8086:0000 Intel, UHCI root hub full speed, self powered, config 1, rev 1.00 driver: uhub7