[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
branch master updated: * tp/Texinfo/XS/parsetexi/input.c (input_push), t
From: |
Patrice Dumas |
Subject: |
branch master updated: * tp/Texinfo/XS/parsetexi/input.c (input_push), tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): pass expanded value and put in value_flag in input structure. Update callers. * tp/Texinfo/XS/parsetexi/input.c (macro_expansion_nr) (value_expansion_nr, next_text), tp/Texinfo/XS/parsetexi/macro.c (handle_macro), tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): use separate counters for values and macros expansions. |
Date: |
Sat, 07 Jan 2023 17:37:48 -0500 |
This is an automated email from the git hooks/post-receive script.
pertusus pushed a commit to branch master
in repository texinfo.
The following commit(s) were added to refs/heads/master by this push:
new 655e78aa6e * tp/Texinfo/XS/parsetexi/input.c (input_push),
tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): pass expanded
value and put in value_flag in input structure. Update callers. *
tp/Texinfo/XS/parsetexi/input.c (macro_expansion_nr) (value_expansion_nr,
next_text), tp/Texinfo/XS/parsetexi/macro.c (handle_macro),
tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): use separate
counters for values and macros expansions.
655e78aa6e is described below
commit 655e78aa6e7846c65c9d23c3ea7b56880a78a421
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sat Jan 7 23:35:47 2023 +0100
* tp/Texinfo/XS/parsetexi/input.c (input_push),
tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): pass
expanded value and put in value_flag in input structure. Update
callers.
* tp/Texinfo/XS/parsetexi/input.c (macro_expansion_nr)
(value_expansion_nr, next_text), tp/Texinfo/XS/parsetexi/macro.c
(handle_macro), tp/Texinfo/XS/parsetexi/parser.c
(process_remaining_on_line): use separate counters for values and
macros expansions.
* tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): error
out on value expansion number higher than MAX_MACRO_CALL_NESTING.
* tp/Texinfo/ParserNonXS.pm (_input_push, _process_remaining_on_line):
put expanded value in iput. Use 'value_flag' for value flag key name
in input.
* tp/Texinfo/ParserNonXS.pm (_input_push, _next_text): fix conditions
on macro being set.
* tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): free
value flag even if there was no value expansion.
* tp/t/50value.t: add recursive_expansion_in_set for a test of infinite
recursion with @value.
---
ChangeLog | 28 ++++++++++++++++++++
tp/TODO | 7 ++---
tp/Texinfo/ParserNonXS.pm | 42 ++++++++++++++----------------
tp/Texinfo/XS/parsetexi/api.c | 6 ++---
tp/Texinfo/XS/parsetexi/handle_commands.c | 2 +-
tp/Texinfo/XS/parsetexi/input.c | 20 +++++++++++---
tp/Texinfo/XS/parsetexi/input.h | 4 ++-
tp/Texinfo/XS/parsetexi/macro.c | 7 ++---
tp/Texinfo/XS/parsetexi/parser.c | 43 +++++++++++++++++++++----------
tp/t/50value.t | 4 +++
10 files changed, 111 insertions(+), 52 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 68f9df77af..b7c3591444 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2023-01-07 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/XS/parsetexi/input.c (input_push),
+ tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): pass
+ expanded value and put in value_flag in input structure. Update
+ callers.
+ * tp/Texinfo/XS/parsetexi/input.c (macro_expansion_nr)
+ (value_expansion_nr, next_text), tp/Texinfo/XS/parsetexi/macro.c
+ (handle_macro), tp/Texinfo/XS/parsetexi/parser.c
+ (process_remaining_on_line): use separate counters for values and
+ macros expansions.
+
+ * tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): error
+ out on value expansion number higher than MAX_MACRO_CALL_NESTING.
+
+ * tp/Texinfo/ParserNonXS.pm (_input_push, _process_remaining_on_line):
+ put expanded value in iput. Use 'value_flag' for value flag key name
+ in input.
+
+ * tp/Texinfo/ParserNonXS.pm (_input_push, _next_text): fix conditions
+ on macro being set.
+
+ * tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): free
+ value flag even if there was no value expansion.
+
+ * tp/t/50value.t: add recursive_expansion_in_set for a test of infinite
+ recursion with @value.
+
2023-01-07 Gavin Smith <gavinsmith0123@gmail.com>
Treat spaces in @verb and @w differently in HTML
diff --git a/tp/TODO b/tp/TODO
index e4a24badfa..accc935612 100644
--- a/tp/TODO
+++ b/tp/TODO
@@ -16,6 +16,8 @@ Bugs
test with cpp directive in macro, verify that file name is stil changed
after the macro expansion
+on the same line as a macro expansion check the source_info, incorrect macro?
+
HTML API
========
@@ -108,11 +110,6 @@ the context command stack.
@end defun
-Recursive expansion of @value may lead to an infinite loop. Fixed in
-pure perl parser, still to be done in XS parser.
- https://bugzilla.redhat.com/show_bug.cgi?id=744878
-
-
In HTML, some @-commands do not have an element with a class associated, or the
association is not perfect. There is @author in @quotation, @-command affected
by @definfoenclose. @pxref and similar @-commands have no class for references
diff --git a/tp/Texinfo/ParserNonXS.pm b/tp/Texinfo/ParserNonXS.pm
index 9d343df133..b78f8d0446 100644
--- a/tp/Texinfo/ParserNonXS.pm
+++ b/tp/Texinfo/ParserNonXS.pm
@@ -792,7 +792,6 @@ sub _input_push($$$;$$)
{
my ($self, $text, $line_nr, $macro_name, $value_name) = @_;
- my $filename;
if (not $self->{'input'}) {
$self->{'input'} = [];
}
@@ -802,16 +801,15 @@ sub _input_push($$$;$$)
$input_source_info->{'file_name'}
= $self->{'input'}->[0]->{'input_source_info'}->{'file_name'};
}
- if (defined($macro_name)) {
+ if (defined($macro_name) and $macro_name ne '') {
$input_source_info->{'macro'} = $macro_name;
} elsif (not defined($value_name)) {
# this counteracts the increment that would follow from the next
# call to _next_text.
$input_source_info->{'line_nr'} -= 1;
}
- $input_source_info->{'file_name'} = $filename if (defined($filename));
my $text_input = _new_text_input($text, $input_source_info);
- $text_input->{'expanded_value'} = 1 if (defined($value_name));
+ $text_input->{'value_flag'} = $value_name if (defined($value_name));
unshift @{$self->{'input'}}, $text_input;
}
@@ -1045,10 +1043,6 @@ sub _setup_conf($$)
if (defined($conf)) {
foreach my $key (keys(%$conf)) {
if (exists($parser_settable_configuration{$key})) {
- #if ($key eq 'info') {
- # # merge hashes prefering values from $conf
- # $parser->{'info'} = { %{$parser->{'info'}}, %{$conf->{'info'}} };
- #}
# we keep registrar instead of copying on purpose, to reuse the object
if ($key ne 'values' and $key ne 'registrar' and ref($conf->{$key})) {
$parser->{$key} = dclone($conf->{$key});
@@ -1493,7 +1487,7 @@ sub _in_paragraph($$)
}
}
-# close brace commands, that don't set a new context (ie @caption, @footnote)
+# close brace commands that don't set a new context (ie not @caption,
@footnote)
sub _close_all_style_commands($$$;$$)
{
my ($self, $current, $source_info, $closed_block_command,
@@ -2197,12 +2191,12 @@ sub _next_text($)
my $texthandle = $input->{'th'};
my $next_line = <$texthandle>;
if (!defined($next_line)) {
- if ($input->{'input_source_info'}->{'macro'}) {
+ if ($input->{'input_source_info'}->{'macro'} ne '') {
my $top_macro = shift @{$self->{'macro_stack'}};
print STDERR "SHIFT MACRO_STACK(@{$self->{'macro_stack'}}):"
." $top_macro->{'args'}->[0]->{'text'}\n"
if ($self->{'DEBUG'});
- } elsif ($input->{'expanded_value'}) {
+ } elsif (defined($input->{'value_flag'})) {
my $top_value = shift @{$self->{'value_stack'}};
print STDERR "SHIFT VALUE_STACK(@{$self->{'value_stack'}}):"
. "$top_value\n"
@@ -2212,8 +2206,8 @@ sub _next_text($)
# need to decode to characters
$next_line = Encode::decode('utf8', $next_line);
$input->{'input_source_info'}->{'line_nr'} += 1
- unless ($input->{'input_source_info'}->{'macro'}
- or $input->{'expanded_value'});
+ unless ($input->{'input_source_info'}->{'macro'} ne ''
+ or defined($input->{'value_flag'}));
return ($next_line, { %{$input->{'input_source_info'}} });
}
} elsif ($input->{'fh'}) {
@@ -4423,7 +4417,7 @@ sub _process_remaining_on_line($$$$)
goto funexit;
}
if ($self->{'MAX_MACRO_CALL_NESTING'}
- and scalar(@{$self->{'macro_stack'}}) >
$self->{'MAX_MACRO_CALL_NESTING'}) {
+ and scalar(@{$self->{'macro_stack'}}) >=
$self->{'MAX_MACRO_CALL_NESTING'}) {
$self->_line_warn(sprintf(__(
"macro call nested too deeply (set MAX_MACRO_CALL_NESTING to override;
current value %d)"),
$self->{'MAX_MACRO_CALL_NESTING'}),
$source_info);
@@ -4466,26 +4460,28 @@ sub _process_remaining_on_line($$$$)
# which may need a well formed tree, which is not needed here, and
# early value expansion may be needed to provide with an argument.
if ($command eq 'value') {
- my $expanded_line = $line;
- substr($expanded_line, 0, $at_command_length) = '';
- $expanded_line =~ s/^\s*//
+ my $remaining_line = $line;
+ substr($remaining_line, 0, $at_command_length) = '';
+ $remaining_line =~ s/^\s*//
if ($self->{'IGNORE_SPACE_AFTER_BRACED_COMMAND_NAME'});
# REVALUE
- if ($expanded_line =~ s/^{([\w\-][^\s{\\}~`\^+"<>|@]*)}//) {
+ if ($remaining_line =~ s/^{([\w\-][^\s{\\}~`\^+"<>|@]*)}//) {
my $value = $1;
if (exists($self->{'values'}->{$value})) {
if ($self->{'MAX_MACRO_CALL_NESTING'}
- and scalar(@{$self->{'value_stack'}}) >
$self->{'MAX_MACRO_CALL_NESTING'}) {
+ and scalar(@{$self->{'value_stack'}}) >=
$self->{'MAX_MACRO_CALL_NESTING'}) {
$self->_line_warn(sprintf(__(
"value call nested too deeply (set MAX_MACRO_CALL_NESTING to override;
current value %d)"),
$self->{'MAX_MACRO_CALL_NESTING'}),
$source_info);
- $line = $expanded_line;
+ $line = $remaining_line;
goto funexit;
}
unshift @{$self->{'value_stack'}}, $value;
- _input_push($self, $expanded_line, $source_info->{'line_nr'},
- $source_info->{'macro'}, $value);
- $line = $self->{'values'}->{$value};
+ _input_push($self, $remaining_line, $source_info->{'line_nr'},
+ $source_info->{'macro'});
+ _input_push($self, $self->{'values'}->{$value},
+ $source_info->{'line_nr'}, $source_info->{'macro'},
$value);
+ $line = '';
goto funexit;
}
}
diff --git a/tp/Texinfo/XS/parsetexi/api.c b/tp/Texinfo/XS/parsetexi/api.c
index 08041b26e6..04aa654906 100644
--- a/tp/Texinfo/XS/parsetexi/api.c
+++ b/tp/Texinfo/XS/parsetexi/api.c
@@ -212,7 +212,7 @@ void
parse_text (char *string, int line_nr)
{
reset_parser_except_conf ();
- input_push (strdup (string), line_nr, 0);
+ input_push (strdup (string), line_nr, 0, 0);
Root = parse_texi_document ();
}
@@ -224,7 +224,7 @@ parse_string (char *string, int line_nr)
ELEMENT *root_elt = new_element (ET_root_line);
reset_parser_except_conf ();
- input_push (strdup (string), line_nr, 0);
+ input_push (strdup (string), line_nr, 0, 0);
Root = parse_texi (root_elt, root_elt);
}
@@ -236,7 +236,7 @@ parse_piece (char *string, int line_nr)
ELEMENT *document_root = before_node_section->parent;
reset_parser_except_conf ();
- input_push (strdup (string), line_nr, 0);
+ input_push (strdup (string), line_nr, 0, 0);
Root = parse_texi (document_root, before_node_section);
}
diff --git a/tp/Texinfo/XS/parsetexi/handle_commands.c
b/tp/Texinfo/XS/parsetexi/handle_commands.c
index 8dfdcc1ba1..2406096cf3 100644
--- a/tp/Texinfo/XS/parsetexi/handle_commands.c
+++ b/tp/Texinfo/XS/parsetexi/handle_commands.c
@@ -353,7 +353,7 @@ handle_line_command (ELEMENT *current, char **line_inout,
char *line2;
SOURCE_INFO save_src_info;
- input_push (strdup (line), current_source_info.line_nr, 0);
+ input_push (strdup (line), current_source_info.line_nr, 0, 0);
save_src_info = current_source_info;
line2 = new_line ();
diff --git a/tp/Texinfo/XS/parsetexi/input.c b/tp/Texinfo/XS/parsetexi/input.c
index e8cd70fce5..45fa5d12ad 100644
--- a/tp/Texinfo/XS/parsetexi/input.c
+++ b/tp/Texinfo/XS/parsetexi/input.c
@@ -48,6 +48,8 @@ typedef struct {
char *text; /* Input text to be parsed as Texinfo. */
char *ptext; /* How far we are through 'text'. Used to split 'text'
into lines. */
+ char *value_flag; /* value flag if the input text is a @value
+ explansion */
} INPUT;
static char *input_pushback_string;
@@ -90,6 +92,8 @@ set_input_encoding (char *encoding)
static INPUT *input_stack = 0;
int input_number = 0;
int input_space = 0;
+int macro_expansion_nr = 0;
+int value_expansion_nr = 0;
/* Current filename and line number. Used for reporting. */
SOURCE_INFO current_source_info;
@@ -412,6 +416,13 @@ next_text (void)
{
/* End of text reached. */
free (i->text);
+ if (i->value_flag)
+ {
+ value_expansion_nr--;
+ free (i->value_flag);
+ }
+ else if (i->source_info.macro)
+ macro_expansion_nr--;
break;
}
/* Split off a line of input. */
@@ -422,7 +433,7 @@ next_text (void)
else
i->ptext = p; /* The next time, we will pop the input source. */
- if (!i->source_info.macro)
+ if (!i->source_info.macro && !i->value_flag)
i->source_info.line_nr++;
current_source_info = i->source_info;
@@ -485,7 +496,7 @@ next_text (void)
string. TEXT will be later free'd and must be allocated on the heap.
MACRO is the name of a macro that the text came from. */
void
-input_push (char *text, int line_number, char *macro)
+input_push (char *text, int line_number, char *macro, char *value_flag)
{
char *filename = 0;
@@ -505,7 +516,7 @@ input_push (char *text, int line_number, char *macro)
input_stack[input_number].text = text;
input_stack[input_number].ptext = text;
- if (!macro)
+ if (!macro && !value_flag)
line_number--;
input_stack[input_number].source_info.line_nr = line_number;
if (input_number > 0)
@@ -514,6 +525,7 @@ input_push (char *text, int line_number, char *macro)
}
input_stack[input_number].source_info.file_name = save_string (filename);
input_stack[input_number].source_info.macro = save_string (macro);
+ input_stack[input_number].value_flag = value_flag;
input_number++;
}
@@ -574,6 +586,8 @@ input_reset_input_stack (void)
}
}
input_number = 0;
+ macro_expansion_nr = 0;
+ value_expansion_nr = 0;
}
int
diff --git a/tp/Texinfo/XS/parsetexi/input.h b/tp/Texinfo/XS/parsetexi/input.h
index 5f18222e33..ba13ca42a0 100644
--- a/tp/Texinfo/XS/parsetexi/input.h
+++ b/tp/Texinfo/XS/parsetexi/input.h
@@ -9,7 +9,7 @@ char *next_text (void);
void save_line_directive (int line_nr, char *filename);
-void input_push (char *text, int line_number, char *macro);
+void input_push (char *text, int line_number, char *macro, char *value_flag);
int input_push_file (char *filename);
void input_pushback (char *line);
void input_reset_input_stack (void);
@@ -28,6 +28,8 @@ void free_small_strings (void);
extern SOURCE_INFO current_source_info;
extern int input_number;
+extern int macro_expansion_nr;
+extern int value_expansion_nr;
extern int doc_encoding_for_input_file_name;
extern char *input_file_name_encoding;
diff --git a/tp/Texinfo/XS/parsetexi/macro.c b/tp/Texinfo/XS/parsetexi/macro.c
index 8c9de1ab4e..efe142ce14 100644
--- a/tp/Texinfo/XS/parsetexi/macro.c
+++ b/tp/Texinfo/XS/parsetexi/macro.c
@@ -559,7 +559,7 @@ handle_macro (ELEMENT *current, char **line_inout, enum
command_id cmd)
expanded.text[--expanded.end] = '\0';
if (conf.max_macro_call_nesting
- && input_number >= conf.max_macro_call_nesting)
+ && macro_expansion_nr >= conf.max_macro_call_nesting)
{
line_warn (
"macro call nested too deeply "
@@ -594,9 +594,10 @@ handle_macro (ELEMENT *current, char **line_inout, enum
command_id cmd)
// 3958 Pop macro stack
/* Put expansion in front of the current line. */
- input_push (strdup (line), current_source_info.line_nr, 0);
+ macro_expansion_nr++;
+ input_push (strdup (line), current_source_info.line_nr, 0, 0);
line = strchr (line, '\0');
- input_push (expanded.text, current_source_info.line_nr, command_name(cmd));
+ input_push (expanded.text, current_source_info.line_nr, command_name(cmd),
0);
funexit:
*line_inout = line;
diff --git a/tp/Texinfo/XS/parsetexi/parser.c b/tp/Texinfo/XS/parsetexi/parser.c
index 65c15b7f1d..7039f98a6a 100644
--- a/tp/Texinfo/XS/parsetexi/parser.c
+++ b/tp/Texinfo/XS/parsetexi/parser.c
@@ -1553,41 +1553,58 @@ superfluous_arg:
and early value expansion may be needed to provide with an argument. */
else if (cmd == CM_value)
{
- char *expanded_line = line_after_command;
+ char *remaining_line = line_after_command;
if (conf.ignore_space_after_braced_command_name)
- expanded_line += strspn (expanded_line, whitespace_chars);
- if (*expanded_line == '{')
+ remaining_line += strspn (remaining_line, whitespace_chars);
+ if (*remaining_line == '{')
{
char *flag;
- expanded_line++;
- flag = read_flag_name (&expanded_line);
+ remaining_line++;
+ flag = read_flag_name (&remaining_line);
if (flag)
{
- if (*expanded_line == '}')
+ if (*remaining_line == '}')
{
char *value;
value = fetch_value (flag);
if (value)
{
- expanded_line++; /* past '}' */
- input_push (strdup (expanded_line),
+ remaining_line++; /* past '}' */
+ if (conf.max_macro_call_nesting
+ && value_expansion_nr >= conf.max_macro_call_nesting)
+ {
+ line_warn (
+ "value call nested too deeply "
+ "(set MAX_MACRO_CALL_NESTING to override; current
value %d)",
+ conf.max_macro_call_nesting);
+ free (flag);
+ line = remaining_line;
+ goto funexit;
+ }
+
+ input_push (strdup (remaining_line),
current_source_info.line_nr,
- current_source_info.macro);
+ current_source_info.macro, 0);
input_push (strdup (value),
current_source_info.line_nr,
- current_source_info.macro);
+ current_source_info.macro,
+ strdup(flag));
+ value_expansion_nr++;
/* Move 'line' to end of string so next input to
be processed is taken from input stack. */
- line = expanded_line + strlen (expanded_line);
+ line = remaining_line + strlen (remaining_line);
retval = STILL_MORE_TO_PROCESS;
}
- free (flag);
if (value)
- goto funexit;
+ {
+ free (flag);
+ goto funexit;
+ }
}
+ free (flag);
}
}
}
diff --git a/tp/t/50value.t b/tp/t/50value.t
index ba5e4c4816..678e661400 100644
--- a/tp/t/50value.t
+++ b/tp/t/50value.t
@@ -61,6 +61,10 @@ Value
@value{myspace}
1
'],
+['recursive_expansion_in_set',
+'@set V @value{V}
+@value{V}
+', {'MAX_MACRO_CALL_NESTING' => 100}],
['value_in_node',
'@set node1 Node 1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- branch master updated: * tp/Texinfo/XS/parsetexi/input.c (input_push), tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): pass expanded value and put in value_flag in input structure. Update callers. * tp/Texinfo/XS/parsetexi/input.c (macro_expansion_nr) (value_expansion_nr, next_text), tp/Texinfo/XS/parsetexi/macro.c (handle_macro), tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line): use separate counters for values and macros expansions.,
Patrice Dumas <=