Skip to content

CloneBlock regexp does not replace the block if line-drop #1800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
juzser opened this issue Jan 7, 2020 · 3 comments
Open

CloneBlock regexp does not replace the block if line-drop #1800

juzser opened this issue Jan 7, 2020 · 3 comments

Comments

@juzser
Copy link
Contributor

juzser commented Jan 7, 2020

Describe the Bug

When you have multiple Blocks in multiple Rows, some of blocks cannot be replaced
Only the last block was replaced.
This because some word file will drop-line after xml tag, and the regular expression engine in different versions cannot find the matched block.

Steps to Reproduce

See the image below, only blocks #6 has been replaced.

  • TemplateProcessor
  • The template has a table with clone rows. Each row has different dynamic data.
  • The blocks name in each row will be block#1, block#2,...

screenshot

<?php
...
$this->processor->cloneRow('client', $amount);
for (...) {
    $suffix = '#' . ($i + 1);
    // block_year.
    $this->processor->cloneBlock('block_year' . $suffix);
}

Expected Behavior

Replaced all Blocks

Current Behavior

Only blocks in the last row was replaced

Context

Please fill in your environment information:

  • PHP Version: 7.3.9
  • PHPWord Version: 0.17.0

Fix & Pull Request:

File: TemplateProcessor.php
Line: 740

Change the regexp pattern to:

'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\${' . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)*?\${\/' . $blockname . '}<\/w:.*?p>)/is',

Describe:

  • Do not find for xml.
  • Start find the <w:p tag that closest to the blockname.
  • This <w:p does not contain any other <w:p inside it.

After fix:
fixed

Hope this helps.

@juzser
Copy link
Contributor Author

juzser commented Jan 21, 2020

Update the regexp to avoid catastrophic backtracking

'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\${' . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\${\/' . $blockname . '}<\/w:.*?p>)/is',

@cawolf
Copy link

cawolf commented Apr 22, 2020

We are also experiencing this issue, and the fix is working. Any chance to get this merged soon?

@dannylifino
Copy link

I have had the same issue, and the provided solution works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants