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(&regex_buff, ltext(clp), RE_NMATCH, regex_match,
-                   REG_STARTEND);
+               if ((search_str = ltext(clp)) == NULL) search_str = "";
+               error = regexec(&regex_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(&regex_buff, ltext(clp), RE_NMATCH, regex_match,
-                   REG_STARTEND) && regex_match[0].rm_so < tbo) {
+               while (!regexec(&regex_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, &regex_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(&regex_buff, ltext(clp), RE_NMATCH,
>regex_match,
>-                   REG_STARTEND);
>+               if ((search_str = ltext(clp)) == NULL) search_str = "";
>+               error = regexec(&regex_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(&regex_buff, ltext(clp), RE_NMATCH,
>regex_match,
>-                   REG_STARTEND) && regex_match[0].rm_so < tbo) {
>+               while (!regexec(&regex_buff, search_str, RE_NMATCH,
>regex_match,
>+                   REG_STARTEND) && regex_match[0].rm_so <= tbo) {
>                        memcpy(&lastmatch, &regex_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


Reply via email to