On Sat, May 18, 2024, at 9:52 AM, Alexander Dunlap wrote:
> On Sat, May 18, 2024, at 2:30 AM, Niranjana K M wrote:
>> Dear LyX developers,
>>     Thank you and congratulations for heading towards much awaited LyX-2.4.
>> I have been using LyX-2.4-RC1 from last 6 months and yesterday accidentally 
>> i caught this strange behavior. And I even installed recently released 
>> LyX-2.4 and the behavior persisted in this version also. But i am not facing 
>> this problem in LyX-2.3.7.
>>     The problem is, when I try to copy, by selecting and pressing Ctrl+C (or 
>> Copy from edit menu), a math block which is boxed and also having deep 
>> nested subscripts to at least 4 levels then my computer memory rapidly got 
>> consumed to the full (starting from 1GB to ~10GB) and in the end LyX closed 
>> with following message.
>> 
>> $ /usr/local/bin/lyx
>> Error: Software exception Detected
>> ----------------------------------------
>> LyX has caught an exception, it will now attempt to save all unsaved 
>> documents and exit.
>> Exception: std::bad_alloc
>> Aborted
>> 
>> Following is the math block which caused it, (LyX code)
>> \begin_inset Formula 
>> \[
>> \boxed{v=\left[v_{p}\right]_{a_{0}}}
>> \]
>> \end_inset
>> 
>> The file is also attached in the end and here is the screenshot of the math 
>> block.
>> Screenshot from 2024-05-18 11-43-00.png
>> 
>> It is a legitimate construction and it gives no problem in LyX-2.3.7 
>> (confirmed).
>> If either the box is removed or the subscript 0 is removed from *a*, then it 
>> has no issues in copying.
>> 
>> All these versions I mentioned were compiled from source on Gentoo Linux. 
>> This LyX-2.4 was compiled with the following configuration,
>> $ ./configure --without-included-boost
>> Configuration
>>   Host type:               x86_64-pc-linux-gnu
>>   Special build flags:      build=release callback-printing use-hunspell 
>> use-aspell use-enchant
>>   Bundled libraries:        nod
>>   C++ Compiler:            g++ (13.2.1)
>>   C++ Compiler flags:       -fPIC -O2 -std=c++17 
>>   C++ Compiler user flags:   -std=c++17  -march=native -O2 -pipe
>>   Linker flags:             -rdynamic
>>   Linker user flags:       
>>   Qt Frontend:
>>       Qt version:   5.15.11
>>   Packaging:               posix
>>   LyX binary dir:          /usr/local/bin
>>   LyX files dir:           /usr/local/share/lyx
>> 
>> I loved the new features in LyX-2.4 and don't want to go back to LyX-2.3.7 
>> due to this issue. Please help in this regard.
> 
> I can reproduce this. I investigated a little and it seems that the problem 
> is that the "while (true)" loop in the splitAndWrapInMText function in 
> InsetMathBox.cpp is never terminating. I believe that the reason for this is 
> that the logic in this function is not correctly identifying the matching 
> XHTML end tag for a given start tag, since it doesn't take into account 
> nested tags properly.

Here is a patch that fixes the problem for me. It needs extensive 
checking/testing though because I do not know too much about XHTML or what all 
sorts of input might be seen in this function.

> 
> 
>> 
>> *Regards*
>> *Niranjana*
>> -- 
>> lyx-devel mailing list
>> lyx-devel@lists.lyx.org
>> http://lists.lyx.org/mailman/listinfo/lyx-devel
>> 
>> 
>> *Attachments:*
>>  • test.24.lyx
> 
From a9d3e6f960265b9097a321ab8fdff41658e31b96 Mon Sep 17 00:00:00 2001
From: Alexander Dunlap <alexander.dun...@gmail.com>
Date: Sat, 18 May 2024 10:12:04 -0400
Subject: [PATCH] Improving logic in splitAndWrapInMText

---
 src/mathed/InsetMathBox.cpp | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/mathed/InsetMathBox.cpp b/src/mathed/InsetMathBox.cpp
index 6feddf9cdd..4295ac0780 100644
--- a/src/mathed/InsetMathBox.cpp
+++ b/src/mathed/InsetMathBox.cpp
@@ -101,9 +101,32 @@ void splitAndWrapInMText(MathMLStream & ms, MathData const & cell,
 		const std::size_t tag_name_length = tag_name_end - 1;
 		const docstring tag_name = inset_contents.substr(1, tag_name_length);
 
-		const std::size_t end_tag_start =
-				inset_contents.find(tag_name, tag_name_end + 1);
-		const std::size_t end_tag = inset_contents.find('>', end_tag_start);
+		// Here we find the matching end tag. We need to take into
+		// account that there may be new tags with the same name opening		// up.
+		int depth = 0;
+		std::size_t end_tag = tag_name_end;
+		std::size_t end_tag_start;
+		while (true) {
+		// Find the next tag with the name we are looking for
+		    end_tag_start = inset_contents.find(tag_name, end_tag + 1);
+		    end_tag = inset_contents.find('>', end_tag_start);
+		    if (inset_contents[end_tag_start-1] == '/') {
+			// if it's a closing tag, then reduce the depth, or if
+			// we are already at depth 0, then we have found the
+			// matching tag
+			if (depth == 0) {
+			    break;
+			} else {
+			    depth--;
+			}
+		    } else {
+			// if it's not a closing tag, then it's a nested opening
+			// tag, so we increase the depth: now we need an
+			// additional closing tag before we have found the
+			// matching one
+			depth++;
+		    }
+                }
 
 		parts.emplace_back(inset_contents.substr(0, end_tag + 1));
 		inset_contents = inset_contents.substr(end_tag + 1);
-- 
2.45.1

-- 
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to