Bug 1867 - sed: 'N' command followed by 'd' produces strange behaviour on subsequent lines
Summary: sed: 'N' command followed by 'd' produces strange behaviour on subsequent lines
Status: RESOLVED FIXED
Alias: None
Product: Busybox
Classification: Unclassified
Component: Other (show other bugs)
Version: 1.16.x
Hardware: PC Linux
: P5 minor
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-30 15:13 UTC by Stephen Bennett
Modified: 2010-06-03 23:31 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stephen Bennett 2010-05-30 15:13:19 UTC
$ echo -e "a\nb\nc\nd" | busybox sed -n '1{N;N;d};2p;3p;4p'
d
d
d

As far as I can tell, on line 1 an 'N' command will result in subsequent address matches for this line matching against both line 1 and line 2; two 'N' commands result in addresses for line 1, 2 and 3 all matching. This much seems reasonable, though I'm not sure what the standard says about it. GNU sed at least will match only line 3 in this situation (the above sed script prints only one "d").

However, following a 'd' command in the same block, this results in the next execution of the script, on input line 4, matching commands for lines 2, 3 and 4. This seems wrong.
Comment 1 Denys Vlasenko 2010-06-03 23:31:14 UTC
Fixed in git, thanks!

Patch:

                /* Are we continuing a previous multi-line match? */
                sed_cmd->in_match = sed_cmd->in_match
                        /* Or is no range necessary? */
                        || (!sed_cmd->beg_line && !sed_cmd->end_line
                                && !sed_cmd->beg_match && !sed_cmd->end_match)
                        /* Or did we match the start of a numerical range? */
-                       || (sed_cmd->beg_line > 0 && (sed_cmd->beg_line <= linenum))
+                       || (sed_cmd->beg_line > 0
+                           && (sed_cmd->end_line || sed_cmd->end_match
+                                 /* note: even if end numeric and is < linenum too,
+                                  * GNU sed matches! We match too */
+                               ? (sed_cmd->beg_line <= linenum)    /* N,end */
+                               : (sed_cmd->beg_line == linenum)    /* N */
+                               )
+                           )
                        /* Or does this line match our begin address regex? */
                        || (beg_match(sed_cmd, pattern_space))
                        /* Or did we match last line of input? */