Skip to content

Commit 3d34021

Browse files
authored
azure-policy parser: allow overriding the column-width limit (microsoft#673)
Some Azure Policy JSON documents contain very long lines — ARM template expressions with deeply nested if()/concat() calls can easily exceed the default 1024-column lexer limit. Add Parser::new_with_max_col() and corresponding parse_policy_rule_with_max_col() / parse_policy_definition_with_max_col() entry points so callers can raise the limit when needed. Also bump ExprParser's own default to 65536 since template expressions are routinely thousands of characters wide.
1 parent 35521ce commit 3d34021

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

src/languages/azure_policy/expr.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ impl<'source> ExprParser<'source> {
7070
fn new(source: &'source Source) -> Self {
7171
let mut lexer = Lexer::new(source);
7272
lexer.set_unknown_char_is_symbol(true);
73+
// ARM template expressions inside Azure Policy JSON values can be
74+
// very long (e.g. deeply nested `if(...)` / `concat(...)` spanning
75+
// thousands of characters on a single line). Use a generous column
76+
// limit so these expressions parse successfully.
77+
if let Some(limit) = core::num::NonZeroU32::new(65536) {
78+
lexer.set_max_col(limit);
79+
}
7380
let tok = Token(
7481
TokenKind::Eof,
7582
Span {

src/languages/azure_policy/parser/core.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,21 @@ pub(super) struct Parser<'source> {
148148
impl<'source> Parser<'source> {
149149
/// Create a new parser for the given source.
150150
pub fn new(source: &'source Source) -> Result<Self, ParseError> {
151+
Self::new_with_max_col(source, None)
152+
}
153+
154+
/// Create a new parser with an optional column-width override.
155+
///
156+
/// When `max_col` is `None`, the lexer's default limit applies.
157+
pub fn new_with_max_col(
158+
source: &'source Source,
159+
max_col: Option<core::num::NonZeroU32>,
160+
) -> Result<Self, ParseError> {
151161
let mut lexer = Lexer::new(source);
152162
lexer.set_unknown_char_is_symbol(true);
163+
if let Some(mc) = max_col {
164+
lexer.set_max_col(mc);
165+
}
153166

154167
let tok = lexer
155168
.next_token()

src/languages/azure_policy/parser/mod.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ pub use error::ParseError;
3434

3535
use alloc::string::ToString as _;
3636

37+
use ::core::num::NonZeroU32;
38+
3739
use crate::lexer::{Source, TokenKind};
3840

3941
use super::ast::{Constraint, FieldKind, OperatorKind, PolicyDefinition, PolicyRule};
@@ -57,7 +59,15 @@ use self::core::Parser;
5759
///
5860
/// Returns a span-annotated [`PolicyRule`] AST.
5961
pub fn parse_policy_rule(source: &Source) -> Result<PolicyRule, ParseError> {
60-
let mut parser = Parser::new(source)?;
62+
parse_policy_rule_with_max_col(source, None)
63+
}
64+
65+
/// Like [`parse_policy_rule`] but with an optional column-width override.
66+
pub fn parse_policy_rule_with_max_col(
67+
source: &Source,
68+
max_col: Option<NonZeroU32>,
69+
) -> Result<PolicyRule, ParseError> {
70+
let mut parser = Parser::new_with_max_col(source, max_col)?;
6171
let rule = parser.parse_policy_rule()?;
6272

6373
if parser.tok.0 != TokenKind::Eof {
@@ -79,7 +89,15 @@ pub fn parse_policy_rule(source: &Source) -> Result<PolicyRule, ParseError> {
7989
/// Returns a [`PolicyDefinition`] with typed fields for known properties
8090
/// and a catch-all list of `extra` entries for everything else.
8191
pub fn parse_policy_definition(source: &Source) -> Result<PolicyDefinition, ParseError> {
82-
let mut parser = Parser::new(source)?;
92+
parse_policy_definition_with_max_col(source, None)
93+
}
94+
95+
/// Like [`parse_policy_definition`] but with an optional column-width override.
96+
pub fn parse_policy_definition_with_max_col(
97+
source: &Source,
98+
max_col: Option<NonZeroU32>,
99+
) -> Result<PolicyDefinition, ParseError> {
100+
let mut parser = Parser::new_with_max_col(source, max_col)?;
83101
let defn = parser.parse_policy_definition()?;
84102

85103
if parser.tok.0 != TokenKind::Eof {

0 commit comments

Comments
 (0)