All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] parse: warn on trailing whitespace after line continuation backslash
@ 2026-08-04  9:08 Jaipaul Cheernam
  2026-08-04 10:27 ` [bitbake-devel] " Richard Purdie
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Jaipaul Cheernam @ 2026-08-04  9:08 UTC (permalink / raw)
  To: bitbake-devel; +Cc: Jaipaul Cheernam

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 5304 bytes --]

rstrip() is called before checking for backslash, so trailing spaces or
tabs after "\" go unnoticed. For example:

    file://foo.patch \<TAB>
    file://bar.patch \

The first line has a trailing tab after the backslash that is invisible
but ends up in patch context, causing patches to fail to apply on trees
where it was cleaned up.

Emit a warning when this is detected so developers can fix it early.

Tested with bitbake-selftest:
  $ python3 -m unittest lib.bb.tests.parse.ParseTest.test_parse_trailing_whitespace_continuation -v
  $ python3 -m unittest lib.bb.tests.parse.ParseTest.test_parse_clean_continuation_no_warning -v

  2 tests OK

Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
---
Problem:
Ran into this while submitting libssh2 CVE patches to both master and
wrynose. The libssh2_1.11.1.bb on master has a stray tab after the
backslash on the CVE-2025-15661-3.patch line. Patches adding new file://
lines below it applied fine on master but git-am refused them on wrynose
because that branch doesn't have the trailing tab — context mismatch.

Other recipes in oe-core with the same issue:
  autoconf_2.73.bb:2
  perl_5.44.0.bb:313,314
  mc_4.8.33.bb:50,51
  libxml-sax-perl_1.02.bb:4

A separate series will follow to fix the trailing whitespace in the
affected recipes.

 lib/bb/parse/parse_py/BBHandler.py   |  6 +++++-
 lib/bb/parse/parse_py/ConfHandler.py | 10 ++++++++--
 lib/bb/tests/parse.py                | 19 +++++++++++++++++++
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/lib/bb/parse/parse_py/BBHandler.py b/lib/bb/parse/parse_py/BBHandler.py
index 008fec230..710ea04d4 100644
--- a/lib/bb/parse/parse_py/BBHandler.py
+++ b/lib/bb/parse/parse_py/BBHandler.py
@@ -104,7 +104,11 @@ def get_statements(filename, absolute_filename, base_name):
                 lineno = lineno + 1
                 s = f.readline()
                 if not s: break
-                s = s.rstrip()
+                # Warn if trailing whitespace exists after a continuation backslash
+                raw = s.rstrip('\n').rstrip('\r')
+                s = raw.rstrip()
+                if s and s[-1] == '\\' and raw != s:
+                    bb.warn("Trailing whitespace after line continuation backslash in %s, line %s" % (filename, lineno))
                 feeder(lineno, s, filename, base_name, statements)
 
         if __inpython__:
diff --git a/lib/bb/parse/parse_py/ConfHandler.py b/lib/bb/parse/parse_py/ConfHandler.py
index 9ddbae123..07b0c371f 100644
--- a/lib/bb/parse/parse_py/ConfHandler.py
+++ b/lib/bb/parse/parse_py/ConfHandler.py
@@ -134,12 +134,18 @@ def handle(fn, data, include, baseconfig=False):
             # skip empty lines
             if not w:
                 continue
-            s = s.rstrip()
+            raw = s.rstrip('\n').rstrip('\r')
+            s = raw.rstrip()
+            if s and s[-1] == '\\' and raw != s:
+                bb.warn("Trailing whitespace after line continuation backslash in %s, line %s" % (fn, lineno))
             while s[-1] == '\\':
                 line = f.readline()
                 origline += line
-                s2 = line.rstrip()
+                raw2 = line.rstrip('\n').rstrip('\r')
+                s2 = raw2.rstrip()
                 lineno = lineno + 1
+                if s2 and s2[-1] == '\\' and raw2 != s2:
+                    bb.warn("Trailing whitespace after line continuation backslash in %s, line %s" % (fn, lineno))
                 if (not s2 or s2 and s2[0] != "#") and s[0] == "#" :
                     bb.fatal("There is a confusing multiline, partially commented expression starting on line %s of file %s:\n%s\nPlease clarify whether this is all a comment or should be parsed." % (origlineno, fn, origline))
 
diff --git a/lib/bb/tests/parse.py b/lib/bb/tests/parse.py
index 6ac2137e0..b01932350 100644
--- a/lib/bb/tests/parse.py
+++ b/lib/bb/tests/parse.py
@@ -638,3 +638,22 @@ EXTRA_OECONF:append = " foobar"
             output = run_bitbake(["bitbake", "-e", "recipe-file1"], builddir, extraenv).splitlines()
             self.assertIn('BBCLASS_FILE="recipe-file.inc"', output)
             self.assertIn(f'BBCLASS_RECIPE_FILE="recipe-file1.bb"', output)
+
+    trailing_whitespace_continuation = "A = \"1 \\\t  \n2\"\n"
+
+    def test_parse_trailing_whitespace_continuation(self):
+        """Test that trailing whitespace after backslash continuation emits a warning"""
+        with self.parsehelper(self.trailing_whitespace_continuation) as f:
+            with self.assertLogs('BitBake', level='WARNING') as cm:
+                d = bb.parse.handle(f.name, self.d)['']
+        self.assertTrue(any("Trailing whitespace after line continuation backslash" in msg for msg in cm.output))
+        # Verify it still parses correctly despite the warning
+        self.assertEqual(d.getVar("A"), "1 2")
+
+    clean_continuation = "A = \"1 \\\n2\"\n"
+
+    def test_parse_clean_continuation_no_warning(self):
+        """Test that clean backslash continuation does not warn"""
+        with self.parsehelper(self.clean_continuation) as f:
+            d = bb.parse.handle(f.name, self.d)['']
+        self.assertEqual(d.getVar("A"), "1 2")


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-08-23  8:14 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-04  9:08 [PATCH] parse: warn on trailing whitespace after line continuation backslash Jaipaul Cheernam
2026-08-04 10:27 ` [bitbake-devel] " Richard Purdie
2026-08-04 10:37   ` Jaipaul Cheernam
2026-08-04 11:37     ` Richard Purdie
2026-08-04 12:15       ` Jaipaul Cheernam
2026-08-06 10:44 ` [PATCH v2] parse: warn on trailing whitespace in parsed lines Jaipaul Cheernam
2026-08-06 11:24 ` Jaipaul Cheernam
2026-08-13 15:07   ` [bitbake-devel] " Mathieu Dubois-Briand
2026-08-13 16:54     ` Jaipaul Cheernam
2026-08-20 10:31       ` Jaipaul Cheernam
2026-08-23  8:14         ` [bitbake-devel] " Mathieu Dubois-Briand

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.