Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version control conflict markers #15294

Closed
p5pRT opened this issue Apr 26, 2016 · 33 comments
Closed

Version control conflict markers #15294

p5pRT opened this issue Apr 26, 2016 · 33 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 26, 2016

Migrated from rt.perl.org#127993 (status was 'resolved')

Searchable as RT127993$

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2016

From @epa

Created by @epa

Sometimes Perl code will appear to compile when there are git conflict
markers like <<<<<<< in the file. Or sometimes it gives an error but
one that doesn't make it clear what the problem really is.

I suggest adding explict detection of <<<<<<< ======= >>>>>>> as
tokens and making them give an immediate error which stops parsing.
As usual, this would not catch 100% of all such errors (the conflict
markers might be inside a here-document, and so on) but it would
be a great help nonetheless.

For C and C++ programs, the latest gcc now reports
  test.c​:3​:1​: error​: version control conflict marker in file
It would be great for perl's error reporting to be as good as C.

Perl Info

Flags:
    category=core
    severity=wishlist

Site configuration information for perl 5.22.1:

Configured by Red Hat, Inc. at Wed Mar  2 13:26:46 UTC 2016.

Summary of my perl5 (revision 5 version 22 subversion 1) configuration:
   
  Platform:
    osname=linux, osvers=4.3.5-300.fc23.x86_64, archname=x86_64-linux-thread-multi
    uname='linux buildvm-19.phx2.fedoraproject.org 4.3.5-300.fc23.x86_64 #1 smp mon feb 1 03:18:41 utc 2016 x86_64 x86_64 x86_64 gnulinux '
    config_args='-des -Doptimize=none -Dccflags=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches  -m64 -mtune=generic -Dldflags=-Wl,-z,relro  -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro  -Dlddlflags=-shared -Wl,-z,relro  -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.22.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='  -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='5.3.1 20151207 (Red Hat 5.3.1-2)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags ='-Wl,-z,relro  -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib
    libs=-lpthread -lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lresolv -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.22.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.22'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro '
    cccdlflags='-fPIC', lddlflags='-shared -Wl,-z,relro  -L/usr/local/lib -fstack-protector-strong'

Locally applied patches:
    Fedora Patch1: Removes date check, Fedora/RHEL specific
    Fedora Patch3: support for libdir64
    Fedora Patch4: use libresolv instead of libbind
    Fedora Patch5: USE_MM_LD_RUN_PATH
    Fedora Patch6: Skip hostname tests, due to builders not being network capable
    Fedora Patch7: Dont run one io test due to random builder failures
    Fedora Patch15: Define SONAME for libperl.so
    Fedora Patch16: Install libperl.so to -Dshrpdir value
    Fedora Patch22: Document Math::BigInt::CalcEmu requires Math::BigInt (CPAN RT#85015)
    Fedora Patch26: Make *DBM_File desctructors thread-safe (RT#61912)
    Fedora Patch27: Make PadlistNAMES() lvalue again (CPAN RT#101063)
    Fedora Patch28: Make magic vtable writable as a work-around for Coro (CPAN RT#101063)
    Fedora Patch29: Fix CVE-2016-2381 (ambiguous environment variables handling)
    Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux
    Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux


@INC for perl 5.22.1:
    /usr/local/lib64/perl5
    /usr/local/share/perl5
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5
    .


Environment for perl 5.22.1:
    HOME=/home/eda
    LANG=en_GB.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=C
    LC_CTYPE=en_GB.UTF-8
    LC_MESSAGES=en_GB.UTF-8
    LC_MONETARY=en_GB.UTF-8
    LC_NUMERIC=en_GB.UTF-8
    LC_TIME=en_GB.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/eda/bin:/home/eda/bin:/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/sbin:/usr/sbin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

Please ignore autogenerated disclaimer below this point.

This email is intended only for the person to whom it is addressed and may contain confidential information. Any retransmission, copying, disclosure or other use of, this information by persons other than the intended recipient is prohibited. If you received this email in error, please contact the sender and delete the material. This email is for information only and is not intended as an offer or solicitation for the purchase or sale of any financial instrument. Wadhwani Asset Management LLP is a Limited Liability Partnership registered in England (OC303168) with registered office at 40 Berkeley Square, 3rd Floor, London, W1J 5AL. It is authorised and regulated by the Financial Conduct Authority.

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2016

From @demerphq

On 26 April 2016 at 09​:04, Ed Avis <perlbug-followup@​perl.org> wrote​:

# New Ticket Created by "Ed Avis"
# Please include the string​: [perl #127993]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=127993 >

This is a bug report for perl from eda@​waniasset.com,
generated with the help of perlbug 1.40 running under perl 5.22.1.

-----------------------------------------------------------------
[Please describe your issue here]

Sometimes Perl code will appear to compile when there are git conflict
markers like <<<<<<< in the file. Or sometimes it gives an error but
one that doesn't make it clear what the problem really is.

I suggest adding explict detection of <<<<<<< ======= >>>>>>> as
tokens and making them give an immediate error which stops parsing.
As usual, this would not catch 100% of all such errors (the conflict
markers might be inside a here-document, and so on) but it would
be a great help nonetheless.

++

Yves

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2016

From @kentfredric

On 26 April 2016 at 19​:04, Ed Avis <perlbug-followup@​perl.org> wrote​:

Sometimes Perl code will appear to compile when there are git conflict
markers like <<<<<<< in the file. Or sometimes it gives an error but
one that doesn't make it clear what the problem really is.

I suggest adding explict detection of <<<<<<< ======= >>>>>>> as
tokens and making them give an immediate error which stops parsing.
As usual, this would not catch 100% of all such errors (the conflict
markers might be inside a here-document, and so on) but it would
be a great help nonetheless.

For C and C++ programs, the latest gcc now reports
test.c​:3​:1​: error​: version control conflict marker in file
It would be great for perl's error reporting to be as good as C.

A CPAN Grep says there's not a lot of risk for a mistake here, a
non-anchored result turns up a few entries, mostly, other code
checking for conflict markers.

<{5,90}.{0,500}={5,90}

http​://grep.cpan.me/?q=%3C{5%2C90}.{0%2C500}%3D{5%2C90}

An Anchored CPAN Grep returns no results, suggesting its probably safe​:

^<{5,90}.{0,500}^={5,90}

http​://grep.cpan.me/?q=^%3C{5%2C90}.{0%2C500}^%3D{5%2C90}

Obviously, C has the Luxury that it doesn't have heredocs.

But fortunately for us,

<<<<<<

Is parsed as

<<"" <<"" <<""

Not

<<"<<<<"

So there's no risk of it being some weird heredoc side-effect either,
and we deprecated <<"" already :D ( See attached hereconflict.pl )

The only thing I'd want to make sure of is how we handled embedded git
conflict markers /inside string literals/ are handled right, because
you never know, there's probably some legitimate usecase for embedding
a conflict inside a heredoc. ( See attached hereconflict2.pl )

--
Kent

KENTNL - https://metacpan.org/author/KENTNL

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2016

From @kentfredric

hereconflict.pl

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2016

From @kentfredric

hereconflict2.pl

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2016

From @epa

I agree, the check would have to be only in code, not inside heredocs or
other quoted strings or __DATA__ or other places where free-form text is
generally allowed. Probably best to allow <<<<<<< and friends inside
regexps too, since there may be code which searches for conflict markers.

As an additional precaution against false positives, these markers could
give an error only when appearing at the start of a line.

Though I do feel in general that tokenization could be a bit stricter,
requiring white space between two punctuation operators when the last
character of the first equals the first character of the second, so that
for example '$a+++5' would be an error rather than equivalent to '$a++ +5'.
There is probably at least some (non-golfing) code using this style, however.

--
Ed Avis <eda@​waniasset.com>

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2016

From @cpansprout

On Tue Apr 26 02​:01​:25 2016, kentfredric@​gmail.com wrote​:

A CPAN Grep says there's not a lot of risk for a mistake here, a
non-anchored result turns up a few entries, mostly, other code
checking for conflict markers.

<{5,90}.{0,500}={5,90}

http​://grep.cpan.me/?q=%3C{5%2C90}.{0%2C500}%3D{5%2C90}

An Anchored CPAN Grep returns no results, suggesting its probably safe​:

^<{5,90}.{0,500}^={5,90}

http​://grep.cpan.me/?q=^%3C{5%2C90}.{0%2C500}^%3D{5%2C90}

Obviously, C has the Luxury that it doesn't have heredocs.

But fortunately for us,

<<<<<<

Is parsed as

<<"" <<"" <<""

Actually <<"" << <<"". That’s a bitshift in the middle.

Not

<<"<<<<"

So there's no risk of it being some weird heredoc side-effect either,
and we deprecated <<"" already :D ( See attached hereconflict.pl )

The only thing I'd want to make sure of is how we handled embedded git
conflict markers /inside string literals/ are handled right, because
you never know, there's probably some legitimate usecase for embedding
a conflict inside a heredoc. ( See attached hereconflict2.pl )

The best thing would be to handle this in yyerror, just the way we do ‘(Missing semicolon?)’. That way, it would never have false positives.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2016

From @demerphq

On 27 April 2016 at 02​:53, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Tue Apr 26 02​:01​:25 2016, kentfredric@​gmail.com wrote​:

A CPAN Grep says there's not a lot of risk for a mistake here, a
non-anchored result turns up a few entries, mostly, other code
checking for conflict markers.

<{5,90}.{0,500}={5,90}

http​://grep.cpan.me/?q=%3C{5%2C90}.{0%2C500}%3D{5%2C90}

An Anchored CPAN Grep returns no results, suggesting its probably safe​:

^<{5,90}.{0,500}^={5,90}

http​://grep.cpan.me/?q=^%3C{5%2C90}.{0%2C500}^%3D{5%2C90}

Obviously, C has the Luxury that it doesn't have heredocs.

But fortunately for us,

<<<<<<

Is parsed as

<<"" <<"" <<""

Actually <<"" << <<"". That’s a bitshift in the middle.

Not

<<"<<<<"

So there's no risk of it being some weird heredoc side-effect either,
and we deprecated <<"" already :D ( See attached hereconflict.pl )

The only thing I'd want to make sure of is how we handled embedded git
conflict markers /inside string literals/ are handled right, because
you never know, there's probably some legitimate usecase for embedding
a conflict inside a heredoc. ( See attached hereconflict2.pl )

The best thing would be to handle this in yyerror, just the way we do ‘(Missing semicolon?)’. That way, it would never have false positives.

Just thought someone should mention we can also check that the token
*starts a line* (or follows a newline or the start of the file,
whatever), so that

my $x= <<<<<<
foo

bar

continues to work just fine.

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @mauke

On Tue Apr 26 00​:04​:31 2016, eda@​waniasset.com wrote​:

This is a bug report for perl from eda@​waniasset.com,
generated with the help of perlbug 1.40 running under perl 5.22.1.

-----------------------------------------------------------------
[Please describe your issue here]

Sometimes Perl code will appear to compile when there are git conflict
markers like <<<<<<< in the file. Or sometimes it gives an error but
one that doesn't make it clear what the problem really is.

I suggest adding explict detection of <<<<<<< ======= >>>>>>> as
tokens and making them give an immediate error which stops parsing.
As usual, this would not catch 100% of all such errors (the conflict
markers might be inside a here-document, and so on) but it would
be a great help nonetheless.

For C and C++ programs, the latest gcc now reports
test.c​:3​:1​: error​: version control conflict marker in file
It would be great for perl's error reporting to be as good as C.

Patch attached. I followed gcc's example​:

+ Specifically, we consider a run of 7 '<', '=' or '>' characters
+ at the start of a line as a patch conflict marker.

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @mauke

0001-recognize-and-reject-version-control-conflict-marker.patch
From ff34a3aa2e1c9a7ef41e1d49a3b978d0c6c21d35 Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Sat, 21 May 2016 10:14:39 +0200
Subject: [PATCH] recognize and reject version control conflict markers (RT
 #127993)

---
 pod/perldiag.pod |  6 ++++++
 t/comp/parser.t  | 21 ++++++++++++++++++++-
 toke.c           | 11 ++++++++++-
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 01f9e29..dc0e369 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -7072,6 +7072,12 @@ S<<-- HERE> in m/%s/
 (F) You used a verb pattern that is not allowed an argument.  Remove the 
 argument or check that you are using the right verb.
 
+=item Version control conflict marker '%s'
+
+(P) The parser found a line starting with C<E<lt><<<<<<>,
+C<E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>>, or C<=======>. These may be left by a
+version control system to mark conflicts after a failed merge operation.
+
 =item Version number must be a constant number
 
 (P) The attempt to translate a C<use Module n.n LIST> statement into
diff --git a/t/comp/parser.t b/t/comp/parser.t
index 50f601c..19d49f9 100644
--- a/t/comp/parser.t
+++ b/t/comp/parser.t
@@ -8,7 +8,7 @@ BEGIN {
     chdir 't' if -d 't';
 }
 
-print "1..173\n";
+print "1..182\n";
 
 sub failed {
     my ($got, $expected, $name) = @_;
@@ -546,6 +546,25 @@ eval "grep+grep";
 eval 'qq{@{0]}${}},{})';
 is(1, 1, "RT #124207");
 
+# RT #127993 version control conflict markers
+" this should keep working
+<<<<<<<
+" =~ /
+>>>>>>>
+/;
+for my $marker (qw(
+<<<<<<<
+=======
+>>>>>>>
+)) {
+    eval "$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 1\./, "VCS marker '$marker' at beginning";
+    eval "\$_\n$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 2\./, "VCS marker '$marker' after value";
+    eval "\n\$_ =\n$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 3\./, "VCS marker '$marker' after operator";
+}
+
 
 # Add new tests HERE (above this line)
 
diff --git a/toke.c b/toke.c
index 4a20e61..6262f4d8 100644
--- a/toke.c
+++ b/toke.c
@@ -5992,6 +5992,8 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '=') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "=====", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (!PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_COMPARE)
                 {
@@ -6106,8 +6108,11 @@ Perl_yylex(pTHX)
 	if (PL_expect != XOPERATOR) {
 	    if (s[1] != '<' && !strchr(s,'>'))
 		check_uni();
-	    if (s[1] == '<' && s[2] != '>')
+	    if (s[1] == '<' && s[2] != '>') {
+	        if ((s == PL_linestart || s[-1] == '\n') && strnEQ(s+2, "<<<<<", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s);
 		s = scan_heredoc(s);
+	    }
 	    else
 		s = scan_inputsymbol(s);
 	    PL_expect = XOPERATOR;
@@ -6117,6 +6122,8 @@ Perl_yylex(pTHX)
 	{
 	    char tmp = *s++;
 	    if (tmp == '<') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "<<<<<", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
@@ -6157,6 +6164,8 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '>') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, ">>>>>", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
-- 
2.8.2

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @mauke

On Sat May 21 01​:27​:22 2016, mauke- wrote​:

On Tue Apr 26 00​:04​:31 2016, eda@​waniasset.com wrote​:

This is a bug report for perl from eda@​waniasset.com,
generated with the help of perlbug 1.40 running under perl 5.22.1.

-----------------------------------------------------------------
[Please describe your issue here]

Sometimes Perl code will appear to compile when there are git conflict
markers like <<<<<<< in the file. Or sometimes it gives an error but
one that doesn't make it clear what the problem really is.

I suggest adding explict detection of <<<<<<< ======= >>>>>>> as
tokens and making them give an immediate error which stops parsing.
As usual, this would not catch 100% of all such errors (the conflict
markers might be inside a here-document, and so on) but it would
be a great help nonetheless.

For C and C++ programs, the latest gcc now reports
test.c​:3​:1​: error​: version control conflict marker in file
It would be great for perl's error reporting to be as good as C.

Patch attached. I followed gcc's example​:

+ Specifically, we consider a run of 7 '<', '=' or '>' characters
+ at the start of a line as a patch conflict marker.

Here's a new patch that also updates perldelta.

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @mauke

0001-recognize-and-reject-version-control-conflict-marker.patch
From 2cb82f9f237e4539f219b278ebf62664e852634c Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Sat, 21 May 2016 10:35:17 +0200
Subject: [PATCH] recognize and reject version control conflict markers (RT
 #127993)

---
 pod/perldelta.pod |  4 ++++
 pod/perldiag.pod  |  6 ++++++
 t/comp/parser.t   | 21 ++++++++++++++++++++-
 toke.c            | 11 ++++++++++-
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index f5bcd6a..e1726f7 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -182,6 +182,10 @@ and New Warnings
 
 =item *
 
+L<Version control conflict marker '%s'|perldiag/"Version control conflict marker '%s'">
+
+=item *
+
 XXX L<message|perldiag/"message">
 
 =back
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 2210a60..cb732d2 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -7058,6 +7058,12 @@ S<<-- HERE> in m/%s/
 (F) You used a verb pattern that is not allowed an argument.  Remove the 
 argument or check that you are using the right verb.
 
+=item Version control conflict marker '%s'
+
+(P) The parser found a line starting with C<E<lt><<<<<<>,
+C<E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>>, or C<=======>. These may be left by a
+version control system to mark conflicts after a failed merge operation.
+
 =item Version number must be a constant number
 
 (P) The attempt to translate a C<use Module n.n LIST> statement into
diff --git a/t/comp/parser.t b/t/comp/parser.t
index 50f601c..19d49f9 100644
--- a/t/comp/parser.t
+++ b/t/comp/parser.t
@@ -8,7 +8,7 @@ BEGIN {
     chdir 't' if -d 't';
 }
 
-print "1..173\n";
+print "1..182\n";
 
 sub failed {
     my ($got, $expected, $name) = @_;
@@ -546,6 +546,25 @@ eval "grep+grep";
 eval 'qq{@{0]}${}},{})';
 is(1, 1, "RT #124207");
 
+# RT #127993 version control conflict markers
+" this should keep working
+<<<<<<<
+" =~ /
+>>>>>>>
+/;
+for my $marker (qw(
+<<<<<<<
+=======
+>>>>>>>
+)) {
+    eval "$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 1\./, "VCS marker '$marker' at beginning";
+    eval "\$_\n$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 2\./, "VCS marker '$marker' after value";
+    eval "\n\$_ =\n$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 3\./, "VCS marker '$marker' after operator";
+}
+
 
 # Add new tests HERE (above this line)
 
diff --git a/toke.c b/toke.c
index 39c59c8..cfe8913 100644
--- a/toke.c
+++ b/toke.c
@@ -5992,6 +5992,8 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '=') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "=====", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (!PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_COMPARE)
                 {
@@ -6106,8 +6108,11 @@ Perl_yylex(pTHX)
 	if (PL_expect != XOPERATOR) {
 	    if (s[1] != '<' && !strchr(s,'>'))
 		check_uni();
-	    if (s[1] == '<' && s[2] != '>')
+	    if (s[1] == '<' && s[2] != '>') {
+	        if ((s == PL_linestart || s[-1] == '\n') && strnEQ(s+2, "<<<<<", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s);
 		s = scan_heredoc(s);
+	    }
 	    else
 		s = scan_inputsymbol(s);
 	    PL_expect = XOPERATOR;
@@ -6117,6 +6122,8 @@ Perl_yylex(pTHX)
 	{
 	    char tmp = *s++;
 	    if (tmp == '<') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "<<<<<", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
@@ -6157,6 +6164,8 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '>') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, ">>>>>", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
-- 
2.8.2

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @cpansprout

On Sat May 21 01​:47​:49 2016, mauke- wrote​:

On Sat May 21 01​:27​:22 2016, mauke- wrote​:

On Tue Apr 26 00​:04​:31 2016, eda@​waniasset.com wrote​:

This is a bug report for perl from eda@​waniasset.com,
generated with the help of perlbug 1.40 running under perl 5.22.1.

-----------------------------------------------------------------
[Please describe your issue here]

Sometimes Perl code will appear to compile when there are git conflict
markers like <<<<<<< in the file. Or sometimes it gives an error but
one that doesn't make it clear what the problem really is.

I suggest adding explict detection of <<<<<<< ======= >>>>>>> as
tokens and making them give an immediate error which stops parsing.
As usual, this would not catch 100% of all such errors (the conflict
markers might be inside a here-document, and so on) but it would
be a great help nonetheless.

For C and C++ programs, the latest gcc now reports
test.c​:3​:1​: error​: version control conflict marker in file
It would be great for perl's error reporting to be as good as C.

Patch attached. I followed gcc's example​:

+ Specifically, we consider a run of 7 '<', '=' or '>' characters
+ at the start of a line as a patch conflict marker.

Here's a new patch that also updates perldelta.

Can the used of s[-1], s[-3], etc. read past the beginning of the buffer? E.g., does eval "<<<<<<" produce a bad read?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @mauke

Am Sa 21. Mai 2016, 05​:25​:24, sprout schrieb​:

On Sat May 21 01​:47​:49 2016, mauke- wrote​:

On Sat May 21 01​:27​:22 2016, mauke- wrote​:

On Tue Apr 26 00​:04​:31 2016, eda@​waniasset.com wrote​:

This is a bug report for perl from eda@​waniasset.com,
generated with the help of perlbug 1.40 running under perl
5.22.1.

-----------------------------------------------------------------
[Please describe your issue here]

Sometimes Perl code will appear to compile when there are git
conflict
markers like <<<<<<< in the file. Or sometimes it gives an error
but
one that doesn't make it clear what the problem really is.

I suggest adding explict detection of <<<<<<< ======= >>>>>>> as
tokens and making them give an immediate error which stops
parsing.
As usual, this would not catch 100% of all such errors (the
conflict
markers might be inside a here-document, and so on) but it would
be a great help nonetheless.

For C and C++ programs, the latest gcc now reports
test.c​:3​:1​: error​: version control conflict marker in file
It would be great for perl's error reporting to be as good as C.

Patch attached. I followed gcc's example​:

+ Specifically, we consider a run of 7 '<', '=' or '>' characters
+ at the start of a line as a patch conflict marker.

Here's a new patch that also updates perldelta.

Can the used of s[-1], s[-3], etc. read past the beginning of the
buffer? E.g., does eval "<<<<<<" produce a bad read?

I copied this logic from the code that deals with "=cut". It should be fine as long as (s >= PL_linestart) holds​: By the time we reach s[-3], we've skipped over two characters (==, >>, <<) in s, so we know s[-1] and s[-2] are OK. The code then checks whether s == PL_linestart+2 first. If it's not, we know s > PL_linestart+2, which makes s[-3] OK.

I haven't actually tried it but I think in eval "<<<<<<" we end up hitting the s == PL_linestart case so s[-1] never runs.

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From zefram@fysh.org

l.mai@​web.de via RT wrote​:

+=item Version control conflict marker '%s'
+
+(P) The parser found a line starting with C<E<lt><<<<<<>,

That "(P)" is not the correct classification. Given your implementation,
it should be "(F)".

-zefram

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @mauke

On Sat May 21 06​:31​:40 2016, zefram@​fysh.org wrote​:

l.mai@​web.de via RT wrote​:

+=item Version control conflict marker '%s'
+
+(P) The parser found a line starting with C<E<lt><<<<<<>,

That "(P)" is not the correct classification. Given your implementation,
it should be "(F)".

You're right. Brainfart on my side. Revised patch attached.

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @mauke

0001-recognize-and-reject-version-control-conflict-marker.patch
From ca733ecaa237d012de2054a759a5357ef22dd985 Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Sat, 21 May 2016 19:12:21 +0200
Subject: [PATCH] recognize and reject version control conflict markers (RT
 #127993)

---
 pod/perldelta.pod |  4 ++++
 pod/perldiag.pod  |  6 ++++++
 t/comp/parser.t   | 21 ++++++++++++++++++++-
 toke.c            | 11 ++++++++++-
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index f5bcd6a..e1726f7 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -182,6 +182,10 @@ and New Warnings
 
 =item *
 
+L<Version control conflict marker '%s'|perldiag/"Version control conflict marker '%s'">
+
+=item *
+
 XXX L<message|perldiag/"message">
 
 =back
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 2210a60..d6c27f9 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -7058,6 +7058,12 @@ S<<-- HERE> in m/%s/
 (F) You used a verb pattern that is not allowed an argument.  Remove the 
 argument or check that you are using the right verb.
 
+=item Version control conflict marker '%s'
+
+(F) The parser found a line starting with C<E<lt><<<<<<>,
+C<E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>>, or C<=======>. These may be left by a
+version control system to mark conflicts after a failed merge operation.
+
 =item Version number must be a constant number
 
 (P) The attempt to translate a C<use Module n.n LIST> statement into
diff --git a/t/comp/parser.t b/t/comp/parser.t
index 50f601c..19d49f9 100644
--- a/t/comp/parser.t
+++ b/t/comp/parser.t
@@ -8,7 +8,7 @@ BEGIN {
     chdir 't' if -d 't';
 }
 
-print "1..173\n";
+print "1..182\n";
 
 sub failed {
     my ($got, $expected, $name) = @_;
@@ -546,6 +546,25 @@ eval "grep+grep";
 eval 'qq{@{0]}${}},{})';
 is(1, 1, "RT #124207");
 
+# RT #127993 version control conflict markers
+" this should keep working
+<<<<<<<
+" =~ /
+>>>>>>>
+/;
+for my $marker (qw(
+<<<<<<<
+=======
+>>>>>>>
+)) {
+    eval "$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 1\./, "VCS marker '$marker' at beginning";
+    eval "\$_\n$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 2\./, "VCS marker '$marker' after value";
+    eval "\n\$_ =\n$marker";
+    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 3\./, "VCS marker '$marker' after operator";
+}
+
 
 # Add new tests HERE (above this line)
 
diff --git a/toke.c b/toke.c
index 39c59c8..cfe8913 100644
--- a/toke.c
+++ b/toke.c
@@ -5992,6 +5992,8 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '=') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "=====", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (!PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_COMPARE)
                 {
@@ -6106,8 +6108,11 @@ Perl_yylex(pTHX)
 	if (PL_expect != XOPERATOR) {
 	    if (s[1] != '<' && !strchr(s,'>'))
 		check_uni();
-	    if (s[1] == '<' && s[2] != '>')
+	    if (s[1] == '<' && s[2] != '>') {
+	        if ((s == PL_linestart || s[-1] == '\n') && strnEQ(s+2, "<<<<<", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s);
 		s = scan_heredoc(s);
+	    }
 	    else
 		s = scan_inputsymbol(s);
 	    PL_expect = XOPERATOR;
@@ -6117,6 +6122,8 @@ Perl_yylex(pTHX)
 	{
 	    char tmp = *s++;
 	    if (tmp == '<') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "<<<<<", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
@@ -6157,6 +6164,8 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '>') {
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, ">>>>>", 5))
+	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
-- 
2.8.2

@p5pRT
Copy link
Author

p5pRT commented May 21, 2016

From @cpansprout

On Sat May 21 05​:37​:59 2016, mauke- wrote​:

Am Sa 21. Mai 2016, 05​:25​:24, sprout schrieb​:

Can the used of s[-1], s[-3], etc. read past the beginning of the
buffer? E.g., does eval "<<<<<<" produce a bad read?

I copied this logic from the code that deals with "=cut". It should be
fine as long as (s >= PL_linestart) holds​: By the time we reach s[-3],
we've skipped over two characters (==, >>, <<) in s, so we know s[-1]
and s[-2] are OK. The code then checks whether s == PL_linestart+2
first. If it's not, we know s > PL_linestart+2, which makes s[-3] OK.

I haven't actually tried it but I think in eval "<<<<<<" we end up
hitting the s == PL_linestart case so s[-1] never runs.

Yes, you’re right. Your patch looks fine, then (specifically, the one with the (F) correction).

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented May 22, 2016

From @mauke

On Sat May 21 11​:45​:10 2016, sprout wrote​:

Yes, you’re right. Your patch looks fine, then (specifically, the one
with the (F) correction).

Now merged as 397c43d.

@p5pRT
Copy link
Author

p5pRT commented May 22, 2016

@mauke - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented May 23, 2016

From @tonycoz

On Sat May 21 10​:13​:47 2016, mauke- wrote​:

On Sat May 21 06​:31​:40 2016, zefram@​fysh.org wrote​:

l.mai@​web.de via RT wrote​:

+=item Version control conflict marker '%s'
+
+(P) The parser found a line starting with C<E<lt><<<<<<>,

That "(P)" is not the correct classification. Given your implementation,
it should be "(F)".

You're right. Brainfart on my side. Revised patch attached.

+ if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "=====", 5))
+ Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);

Shouldn't the errors be reported with yyerror() (or one of its variants) ?

Tony

@p5pRT
Copy link
Author

p5pRT commented May 23, 2016

From @cpansprout

On Sun May 22 17​:57​:48 2016, tonyc wrote​:

Shouldn't the errors be reported with yyerror() (or one of its
variants) ?

Tony

It depends on whether you want perl to continue parsing and reporting other possible errors. In this case, I’m not sure that would make much sense.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented May 23, 2016

From @mauke

Am So 22. Mai 2016, 17​:57​:48, tonyc schrieb​:

+ if ((s == PL_linestart+2 || s[-3] == '\n') &&
strnEQ(s, "=====", 5))
+ Perl_croak(aTHX_ "Version control conflict marker
'%.*s'", 7, s - 2);

Shouldn't the errors be reported with yyerror() (or one of its
variants) ?

I tried that, but it added "at end of line" to the message, followed by another syntax error for "==".

@p5pRT
Copy link
Author

p5pRT commented May 23, 2016

From @tonycoz

On Sun, May 22, 2016 at 06​:32​:52PM -0700, l.mai@​web.de via RT wrote​:

Am So 22. Mai 2016, 17​:57​:48, tonyc schrieb​:

+ if ((s == PL_linestart+2 || s[-3] == '\n') &&
strnEQ(s, "=====", 5))
+ Perl_croak(aTHX_ "Version control conflict marker
'%.*s'", 7, s - 2);

Shouldn't the errors be reported with yyerror() (or one of its
variants) ?

I tried that, but it added "at end of line" to the message, followed by another syntax error for "==".

You'd also want to skip parsing to the next line (as with a comment),
maybe it can pick up any other conflict markers.

Also, git can add |||||| conflict to separate the original text if you
set merge.conflictstyle to diff3.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2016

From @mauke

On Sun May 22 19​:04​:46 2016, tonyc wrote​:

On Sun, May 22, 2016 at 06​:32​:52PM -0700, l.mai@​web.de via RT wrote​:

Am So 22. Mai 2016, 17​:57​:48, tonyc schrieb​:

+ if ((s == PL_linestart+2 || s[-3] == '\n') &&
strnEQ(s, "=====", 5))
+ Perl_croak(aTHX_ "Version control conflict
marker
'%.*s'", 7, s - 2);

Shouldn't the errors be reported with yyerror() (or one of its
variants) ?

I tried that, but it added "at end of line" to the message, followed
by another syntax error for "==".

You'd also want to skip parsing to the next line (as with a comment),
maybe it can pick up any other conflict markers.

I've attached a patch to do it that way. Any comments?

Also, git can add |||||| conflict to separate the original text if you
set merge.conflictstyle to diff3.

I didn't add that one initially because gcc doesn't recognize it either. Should I?

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2016

From @mauke

0001-use-yyerror-instead-of-croaking-immediately-RT-12799.patch
From 0e7163d07e4baa9a920c10d18b8da09f3254db42 Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Sat, 4 Jun 2016 13:05:36 +0200
Subject: [PATCH] use yyerror instead of croaking immediately (RT #127993)

---
 pod/perldelta.pod |  2 +-
 pod/perldiag.pod  |  2 +-
 t/comp/parser.t   |  6 +++---
 toke.c            | 52 ++++++++++++++++++++++++++++++++++++----------------
 4 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 69a3d53..97f8444 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -204,7 +204,7 @@ and New Warnings
 
 =item *
 
-L<Version control conflict marker '%s'|perldiag/"Version control conflict marker '%s'">
+L<Version control conflict marker|perldiag/"Version control conflict marker">
 
 =item *
 
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index fdf79c8..dae7c26 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -7057,7 +7057,7 @@ S<<-- HERE> in m/%s/
 (F) You used a verb pattern that is not allowed an argument.  Remove the 
 argument or check that you are using the right verb.
 
-=item Version control conflict marker '%s'
+=item Version control conflict marker
 
 (F) The parser found a line starting with C<E<lt><<<<<<>,
 C<E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>E<gt>>, or C<=======>. These may be left by a
diff --git a/t/comp/parser.t b/t/comp/parser.t
index 19d49f9..efd3a8d 100644
--- a/t/comp/parser.t
+++ b/t/comp/parser.t
@@ -558,11 +558,11 @@ for my $marker (qw(
 >>>>>>>
 )) {
     eval "$marker";
-    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 1\./, "VCS marker '$marker' at beginning";
+    like $@, qr/^Version control conflict marker at \(eval \d+\) line 1, near "$marker"/, "VCS marker '$marker' at beginning";
     eval "\$_\n$marker";
-    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 2\./, "VCS marker '$marker' after value";
+    like $@, qr/^Version control conflict marker at \(eval \d+\) line 2, near "$marker"/, "VCS marker '$marker' after value";
     eval "\n\$_ =\n$marker";
-    like $@, qr/^Version control conflict marker '$marker' at \(eval \d+\) line 3\./, "VCS marker '$marker' after operator";
+    like $@, qr/^Version control conflict marker at \(eval \d+\) line 3, near "$marker"/, "VCS marker '$marker' after operator";
 }
 
 
diff --git a/toke.c b/toke.c
index e6f6bf9..327d984 100644
--- a/toke.c
+++ b/toke.c
@@ -4422,6 +4422,26 @@ S_check_scalar_slice(pTHX_ char *s)
 	pl_yylval.ival = OPpSLICEWARNING;
 }
 
+#define lex_token_boundary() S_lex_token_boundary(aTHX)
+static void
+S_lex_token_boundary(pTHX)
+{
+    PL_oldoldbufptr = PL_oldbufptr;
+    PL_oldbufptr = PL_bufptr;
+}
+
+#define vcs_conflict_marker(s) S_vcs_conflict_marker(aTHX_ s)
+static char *
+S_vcs_conflict_marker(pTHX_ char *s)
+{
+    lex_token_boundary();
+    PL_bufptr = s;
+    yyerror("Version control conflict marker");
+    while (s < PL_bufend && *s != '\n')
+	s++;
+    return s;
+}
+
 /*
   yylex
 
@@ -5992,8 +6012,10 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '=') {
-	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "=====", 5))
-	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "=====", 5)) {
+	            s = vcs_conflict_marker(s + 5);
+	            goto retry;
+	        }
 		if (!PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_COMPARE)
                 {
@@ -6109,8 +6131,10 @@ Perl_yylex(pTHX)
 	    if (s[1] != '<' && !strchr(s,'>'))
 		check_uni();
 	    if (s[1] == '<' && s[2] != '>') {
-	        if ((s == PL_linestart || s[-1] == '\n') && strnEQ(s+2, "<<<<<", 5))
-	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s);
+	        if ((s == PL_linestart || s[-1] == '\n') && strnEQ(s+2, "<<<<<", 5)) {
+	            s = vcs_conflict_marker(s + 7);
+	            goto retry;
+	        }
 		s = scan_heredoc(s);
 	    }
 	    else
@@ -6122,8 +6146,10 @@ Perl_yylex(pTHX)
 	{
 	    char tmp = *s++;
 	    if (tmp == '<') {
-	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "<<<<<", 5))
-	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, "<<<<<", 5)) {
+                    s = vcs_conflict_marker(s + 5);
+	            goto retry;
+	        }
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
@@ -6164,8 +6190,10 @@ Perl_yylex(pTHX)
 	{
 	    const char tmp = *s++;
 	    if (tmp == '>') {
-	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, ">>>>>", 5))
-	            Perl_croak(aTHX_ "Version control conflict marker '%.*s'", 7, s - 2);
+	        if ((s == PL_linestart+2 || s[-3] == '\n') && strnEQ(s, ">>>>>", 5)) {
+	            s = vcs_conflict_marker(s + 5);
+	            goto retry;
+	        }
 		if (*s == '=' && !PL_lex_allbrackets
                     && PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
                 {
@@ -11827,14 +11855,6 @@ Perl_parse_stmtseq(pTHX_ U32 flags)
     return stmtseqop;
 }
 
-#define lex_token_boundary() S_lex_token_boundary(aTHX)
-static void
-S_lex_token_boundary(pTHX)
-{
-    PL_oldoldbufptr = PL_oldbufptr;
-    PL_oldbufptr = PL_bufptr;
-}
-
 #define parse_opt_lexvar() S_parse_opt_lexvar(aTHX)
 static OP *
 S_parse_opt_lexvar(pTHX)
-- 
2.8.3

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2016

From @cpansprout

On Sat Jun 04 04​:08​:48 2016, mauke- wrote​:

On Sun May 22 19​:04​:46 2016, tonyc wrote​:

On Sun, May 22, 2016 at 06​:32​:52PM -0700, l.mai@​web.de via RT wrote​:

Am So 22. Mai 2016, 17​:57​:48, tonyc schrieb​:

+ if ((s == PL_linestart+2 || s[-3] == '\n') &&
strnEQ(s, "=====", 5))
+ Perl_croak(aTHX_ "Version control conflict
marker
'%.*s'", 7, s - 2);

Shouldn't the errors be reported with yyerror() (or one of its
variants) ?

I tried that, but it added "at end of line" to the message,
followed
by another syntax error for "==".

You'd also want to skip parsing to the next line (as with a comment),
maybe it can pick up any other conflict markers.

I've attached a patch to do it that way. Any comments?

It looks good to me, though I did look at it rather quickly.

Also, git can add |||||| conflict to separate the original text if
you
set merge.conflictstyle to diff3.

I didn't add that one initially because gcc doesn't recognize it
either. Should I?

I have no opinion on that.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 6, 2016

From @tonycoz

On Sat Jun 04 04​:08​:48 2016, mauke- wrote​:

On Sun May 22 19​:04​:46 2016, tonyc wrote​:

On Sun, May 22, 2016 at 06​:32​:52PM -0700, l.mai@​web.de via RT wrote​:

Am So 22. Mai 2016, 17​:57​:48, tonyc schrieb​:

+ if ((s == PL_linestart+2 || s[-3] == '\n') &&
strnEQ(s, "=====", 5))
+ Perl_croak(aTHX_ "Version control conflict
marker
'%.*s'", 7, s - 2);

Shouldn't the errors be reported with yyerror() (or one of its
variants) ?

I tried that, but it added "at end of line" to the message,
followed
by another syntax error for "==".

You'd also want to skip parsing to the next line (as with a comment),
maybe it can pick up any other conflict markers.

I've attached a patch to do it that way. Any comments?

Also, git can add |||||| conflict to separate the original text if
you
set merge.conflictstyle to diff3.

I didn't add that one initially because gcc doesn't recognize it
either. Should I?

Up to you, it's going to be a lot rarer.

I would have pushed your patch to blead but the git server is out of disk space.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jun 7, 2016

From @tonycoz

On Sun Jun 05 17​:46​:02 2016, tonyc wrote​:

On Sat Jun 04 04​:08​:48 2016, mauke- wrote​:

On Sun May 22 19​:04​:46 2016, tonyc wrote​:

On Sun, May 22, 2016 at 06​:32​:52PM -0700, l.mai@​web.de via RT
wrote​:

Am So 22. Mai 2016, 17​:57​:48, tonyc schrieb​:

+ if ((s == PL_linestart+2 || s[-3] == '\n') &&
strnEQ(s, "=====", 5))
+ Perl_croak(aTHX_ "Version control conflict
marker
'%.*s'", 7, s - 2);

Shouldn't the errors be reported with yyerror() (or one of its
variants) ?

I tried that, but it added "at end of line" to the message,
followed
by another syntax error for "==".

You'd also want to skip parsing to the next line (as with a
comment),
maybe it can pick up any other conflict markers.

I've attached a patch to do it that way. Any comments?

Also, git can add |||||| conflict to separate the original text if
you
set merge.conflictstyle to diff3.

I didn't add that one initially because gcc doesn't recognize it
either. Should I?

Up to you, it's going to be a lot rarer.

I would have pushed your patch to blead but the git server is out of
disk space.

Thanks, applied as 9c88bb5.

I also added a test for multiple markers in e2733f9.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jun 9, 2016

From @epa

Thanks all for your work on this.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release today of Perl 5.26.0, this and 210 other issues have been
resolved.

Perl 5.26.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.26.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

@khwilliamson - Status changed from 'pending release' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant