Skip to content

Commit 627f507

Browse files
authored
hrw4u: Fix section placement for hookless rules in u4wrh (#12956)
Old header_rewrite rules without an explicit hook condition default to REMAP. When u4wrh converted these, the section opened inside the if-block instead of wrapping it. Also emit comments inline inside if-blocks instead of deferring them to after the section closes, and remove the now-unused deferred comment machinery. In the forward direction, indent block-level comments at the statement level. Co-Authored-By: Keele Clendenin
1 parent 3b3650e commit 627f507

6 files changed

Lines changed: 39 additions & 20 deletions

File tree

tools/hrw4u/src/hrw_visitor.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def __init__(
5757
self._if_depth = 0 # Track nesting depth of if blocks
5858
self._in_elif_mode = False
5959
self._just_closed_nested = False
60-
self._deferred_comments: list[str] = []
60+
61+
self._pre_section_if_start: int | None = None
6162

6263
@lru_cache(maxsize=128)
6364
def _cached_percent_parsing(self, pct_text: str) -> tuple[str, str | None]:
@@ -84,12 +85,6 @@ def _reset_condition_state(self) -> None:
8485
self._in_group = False
8586
self._group_terms.clear()
8687

87-
def _flush_deferred_comments(self) -> None:
88-
"""Emit comments that were deferred while inside a rule's if-block."""
89-
for comment in self._deferred_comments:
90-
self.output.append(comment)
91-
self._deferred_comments.clear()
92-
9388
def _start_new_section(self, section_type: SectionType) -> None:
9489
"""Start a new section, handling continuation of existing sections."""
9590
with self.debug_context(f"start_section {section_type.value}"):
@@ -100,21 +95,17 @@ def _start_new_section(self, section_type: SectionType) -> None:
10095
self.emit("}")
10196
self._if_depth -= 1
10297
self._reset_condition_state()
103-
self._flush_deferred_comments()
10498
if self.output and self.output[-1] != "":
10599
self.output.append("")
106100
return
107101

108-
prev = bool(self.output)
109102
had_section = self._section_opened
110103
self._close_if_and_section()
111104
self._reset_condition_state()
112105

113106
if had_section and self.output and self.output[-1] != "":
114107
self.output.append("")
115108

116-
self._flush_deferred_comments()
117-
118109
self._section_label = section_type
119110
self.emit(f"{section_type.value} {{")
120111
self._section_opened = True
@@ -162,7 +153,6 @@ def visitProgram(self, ctx: u4wrhParser.ProgramContext) -> list[str]:
162153
for line in ctx.line():
163154
self.visit(line)
164155
self._close_if_and_section()
165-
self._flush_deferred_comments()
166156

167157
var_declarations = self.symbol_resolver.get_var_declarations()
168158
if var_declarations:
@@ -178,9 +168,7 @@ def visitCommentLine(self, ctx: u4wrhParser.CommentLineContext) -> None:
178168
with self.debug_context("visitCommentLine"):
179169
comment_text = ctx.COMMENT().getText()
180170
self._flush_pending_condition()
181-
if self._if_depth > 0:
182-
self._deferred_comments.append(comment_text)
183-
elif self._section_opened:
171+
if self._if_depth > 0 or self._section_opened:
184172
self.emit(comment_text)
185173
else:
186174
self.output.append(comment_text)
@@ -407,10 +395,27 @@ def _close_if_and_section(self) -> None:
407395
def _ensure_section_open(self, section_label: SectionType) -> None:
408396
"""Ensure a section is open for statements."""
409397
if not self._section_opened:
398+
relocated_lines = None
399+
relocated_if_depth = 0
400+
if self._if_depth > 0 and self._pre_section_if_start is not None:
401+
relocated_lines = self.output[self._pre_section_if_start:]
402+
relocated_if_depth = self._if_depth
403+
self.output = self.output[:self._pre_section_if_start]
404+
self.stmt_indent -= self._if_depth
405+
self._if_depth = 0
406+
self._pre_section_if_start = None
407+
410408
self.emit(f"{section_label.value} {{")
411409
self._section_opened = True
412410
self.increase_indent()
413411

412+
if relocated_lines:
413+
indent_prefix = " " * SystemDefaults.INDENT_SPACES
414+
for line in relocated_lines:
415+
self.output.append(indent_prefix + line if line.strip() else line)
416+
self._if_depth = relocated_if_depth
417+
self.stmt_indent += relocated_if_depth
418+
414419
def _start_elif_mode(self) -> None:
415420
"""Handle elif line transitions."""
416421
# After endif, we need to close the parent if-statement
@@ -432,6 +437,9 @@ def _handle_else_transition(self) -> None:
432437

433438
def _start_if_block(self, condition_expr: str) -> None:
434439
"""Start a new if block."""
440+
if not self._section_opened and self._pre_section_if_start is None:
441+
self._pre_section_if_start = len(self.output)
442+
435443
if self._in_elif_mode:
436444
self.emit(f"}} elif {condition_expr} {{")
437445
self._in_elif_mode = False

tools/hrw4u/src/visitor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ def visitCommentLine(self, ctx) -> None:
830830
with self.debug_context("visitCommentLine"):
831831
comment_text = ctx.COMMENT().getText()
832832
self.debug(f"preserving comment: {comment_text}")
833-
self.output.append(comment_text)
833+
self.emit_line(comment_text, self.stmt_indent)
834834

835835
def visitStatement(self, ctx) -> None:
836836
with self.debug_context("visitStatement"), self.trap(ctx):

tools/hrw4u/tests/data/conds/exceptions.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
implicit-cmp.input: u4wrh
66
# Double negation !(x != y) emits GROUP/GROUP:END [NOT] pairs; reverse can't reconstruct the original form
77
double-negation.input: hrw4u
8+
# Old format without explicit hook defaults to REMAP; hrw4u always emits explicit sections
9+
no-hook.input: u4wrh
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
REMAP {
2+
if inbound.req.Debug {
3+
# to return the debug header if http header debug: on
4+
inbound.req.@DebugHeader = "TRUE";
5+
}
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
cond %{CLIENT-HEADER:Debug} ="" [NOT]
2+
# to return the debug header if http header debug: on
3+
set-header @DebugHeader "TRUE"

tools/hrw4u/tests/data/examples/all-nonsense.output.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ cond %{GROUP}
9393
cond %{GROUP:END}
9494
skip-remap TRUE
9595
no-op [L]
96-
# like [L]
96+
# like [L]
9797

9898
cond %{READ_REQUEST_HDR_HOOK} [AND]
9999
# Header presence / equality and capture groups
@@ -132,9 +132,9 @@ cond %{GROUP}
132132
cond %{GROUP:END}
133133
counter "write_methods_seen"
134134
set-state-int8 0 42
135-
# assign int8
135+
# assign int8
136136
set-state-int16 0 6553
137-
# assign int16
137+
# assign int16
138138

139139
cond %{SEND_REQUEST_HDR_HOOK} [AND]
140140
# Use server URL information to adjust Host header
@@ -174,7 +174,7 @@ elif
174174
cond %{CACHE} ("miss","skipped")
175175
cond %{GROUP:END}
176176
set-header X-Cache "%{CACHE}"
177-
# echo the value
177+
# echo the value
178178
# Status transforms + reason
179179

180180
cond %{READ_RESPONSE_HDR_HOOK} [AND]

0 commit comments

Comments
 (0)