Folks, Of course, my patch was wrong. Insufficient testing with ³unimportant² conditions. Sorry, guys.
The issue was with point (3), where the original patch skipped valid matches when searching backwards. The patch below appears to be more robust: --- a/re_search.c Tue Apr 10 15:36:48 2018 +++ b/re_search.c Fri Apr 20 20:30:03 2018 @@ -310,6 +310,7 @@ { int tbo, tdotline, error; struct line *clp; + char *search_str; clp = curwp->w_dotp; tbo = curwp->w_doto; @@ -332,8 +333,9 @@ while (clp != (curbp->b_headp)) { regex_match[0].rm_so = tbo; regex_match[0].rm_eo = llength(clp); - error = regexec(®ex_buff, ltext(clp), RE_NMATCH, regex_match, - REG_STARTEND); + if ((search_str = ltext(clp)) == NULL) search_str = ""; + error = regexec(®ex_buff, search_str, RE_NMATCH, regex_match, + (tbo==0?0:REG_NOTBOL)|REG_STARTEND); if (error != 0) { clp = lforw(clp); tdotline++; @@ -361,6 +363,7 @@ struct line *clp; int tbo, tdotline; regmatch_t lastmatch; + char *search_str; clp = curwp->w_dotp; tbo = curwp->w_doto; @@ -383,15 +386,19 @@ regex_match[0].rm_so = 0; regex_match[0].rm_eo = llength(clp); lastmatch.rm_so = -1; + if ((search_str = ltext(clp)) == NULL) search_str = ""; /* * Keep searching until we don't match any longer. Assumes a * non-match does not modify the regex_match array. We have to * do this character-by-character after the first match since * POSIX regexps don't give you a way to do reverse matches. */ - while (!regexec(®ex_buff, ltext(clp), RE_NMATCH, regex_match, - REG_STARTEND) && regex_match[0].rm_so < tbo) { + while (!regexec(®ex_buff, search_str, RE_NMATCH, regex_match, + (regex_match[0].rm_so == 0?0:REG_NOTBOL)|REG_STARTEND) + && regex_match[0].rm_so <= tbo) { memcpy(&lastmatch, ®ex_match[0], sizeof(regmatch_t)); + if (regex_match[0].rm_so == 0 && + regex_match[0].rm_eo == 0) break; regex_match[0].rm_so++; regex_match[0].rm_eo = llength(clp); } -mark On 14/04/2018, 20:47, "m...@hydrus.org.uk" <m...@hydrus.org.uk> wrote: >>Synopsis: Defects in mg text editor related to regex searching >>Category: user >>Environment: > System : OpenBSD 6.3 > Details : OpenBSD 6.3 (GENERIC.MP) #107: Sat Mar 24 14:21:59 MDT > 2018 > > dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP > > Architecture: OpenBSD.amd64 Machine : amd64 > >>Description: > The attached fix solves the following defects found in > the mg text editor: > > 1. Replacing text with the query-replace-regexp command using aa > regex string that contains only start-of-line anchor ("^") > insists on inserting text on the current line. > > 2. Replacing text on an empty line (i.e. lines with only "\n") > with query-replace-regexp causes a "Segmentation Fault" > > 3. search-backward-regexp where the regex string only contains a > EOL anchor "$" always fails > > 4. search-backward-regexp for a string containing an anchor of "$" > causes a Segmentation Fault, where lines are empty (lines with > only "\n") > >>How-To-Repeat: > Please see above. > >>Fix: >--- a/re_search.c Tue Apr 10 15:36:48 2018 >+++ b/re_search.c Sat Apr 14 15:59:13 2018 >@@ -310,6 +310,7 @@ > { > int tbo, tdotline, error; > struct line *clp; >+ char *search_str; > > clp = curwp->w_dotp; > tbo = curwp->w_doto; >@@ -332,8 +333,9 @@ > while (clp != (curbp->b_headp)) { > regex_match[0].rm_so = tbo; > regex_match[0].rm_eo = llength(clp); >- error = regexec(®ex_buff, ltext(clp), RE_NMATCH, >regex_match, >- REG_STARTEND); >+ if ((search_str = ltext(clp)) == NULL) search_str = ""; >+ error = regexec(®ex_buff, search_str, RE_NMATCH, >regex_match, >+ (tbo==0?0:REG_NOTBOL)|REG_STARTEND); > if (error != 0) { > clp = lforw(clp); > tdotline++; >@@ -361,6 +363,7 @@ > struct line *clp; > int tbo, tdotline; > regmatch_t lastmatch; >+ char *search_str; > > clp = curwp->w_dotp; > tbo = curwp->w_doto; >@@ -383,15 +386,17 @@ > regex_match[0].rm_so = 0; > regex_match[0].rm_eo = llength(clp); > lastmatch.rm_so = -1; >+ if ((search_str = ltext(clp)) == NULL) search_str = ""; > /* > * Keep searching until we don't match any longer. >Assumes a > * non-match does not modify the regex_match array. We >have to > * do this character-by-character after the first match >since > * POSIX regexps don't give you a way to do reverse >matches. > */ >- while (!regexec(®ex_buff, ltext(clp), RE_NMATCH, >regex_match, >- REG_STARTEND) && regex_match[0].rm_so < tbo) { >+ while (!regexec(®ex_buff, search_str, RE_NMATCH, >regex_match, >+ REG_STARTEND) && regex_match[0].rm_so <= tbo) { > memcpy(&lastmatch, ®ex_match[0], >sizeof(regmatch_t)); >+ if (regex_match[0].rm_eo == tbo) break; > regex_match[0].rm_so++; > regex_match[0].rm_eo = llength(clp); > } > > >dmesg: >OpenBSD 6.3 (GENERIC.MP) #107: Sat Mar 24 14:21:59 MDT 2018 > dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP >real mem = 8523141120 (8128MB) >avail mem = 8257761280 (7875MB) >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: rev 2 >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.37 MHz >cpu0: >FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CF >LUSH,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,ME >LTDOWN >cpu0: 3MB 64b/line 8-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.01 MHz >cpu1: >FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CF >LUSH,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,ME >LTDOWN >cpu1: 3MB 64b/line 8-way L2 cache >cpu1: smt 0, core 1, package 0 >ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 24 pins >, remapped to apid 2 >acpimcfg0 at acpi0 addr 0xf8000000, bus 0-63 >acpiprt0 at acpi0: bus 3 (PCIE) >acpiprt1 at acpi0: bus -1 (AGP_) >acpiprt2 at acpi0: bus 11 (RP01) >acpiprt3 at acpi0: bus 12 (RP02) >acpiprt4 at acpi0: bus 13 (RP03) >acpiprt5 at acpi0: bus 14 (RP04) >acpiprt6 at acpi0: bus -1 (RP05) >acpiprt7 at acpi0: bus -1 (RP06) >acpiprt8 at acpi0: bus 0 (PCI0) >acpiec0 at acpi0 >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 >acpibtn0 at acpi0: LID_ >acpibtn1 at acpi0: PBTN >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 >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: msi >inteldrm0: 1920x1200, 32bpp >wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation) >wsdisplay0: screen 1-5 added (std, vt100 emulation) >"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.0, 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> SCSI3 >0/direct fixed naa.50026b775605cd58 >sd0: 228936MB, 512 bytes/sector, 468862128 sectors, thin >cd0 at scsibus1 targ 1 lun 0: <TSSTcorp, DVD+-RW TS-U633F, D500> ATAPI >5/cdrom 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, using wsdisplay0 >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: VMX >ugen0 at uhub4 port 1 "Broadcom Corp 5880" rev 1.10/1.01 addr 2 >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 > >usbdevs: >Controller /dev/usb0: >addr 1: high speed, self powered, config 1, EHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 powered > port 2 powered > port 3 powered > port 4 powered > port 5 powered > port 6 powered >Controller /dev/usb1: >addr 1: high speed, self powered, config 1, EHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 powered > port 2 powered > port 3 powered > port 4 powered > port 5 powered > port 6 powered >Controller /dev/usb2: >addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 powered > port 2 powered >Controller /dev/usb3: >addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 powered > port 2 powered >Controller /dev/usb4: >addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 addr 2: full speed, power 100 mA, unconfigured, 5880(0x5800), >Broadcom Corp(0x0a5c), rev 1.01, iSerialNumber 0123456789ABCD > port 2 powered >Controller /dev/usb5: >addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 powered > port 2 powered >Controller /dev/usb6: >addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 powered > port 2 powered >Controller /dev/usb7: >addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), >Intel(0x8086), rev 1.00 > port 1 powered > port 2 powered