jabref icon indicating copy to clipboard operation
jabref copied to clipboard

Add recovery method to solve unbalanced brackets

Open hisunll opened this issue 3 weeks ago • 2 comments

Closes https://github.com/JabRef/jabref/issues/9833

I added bracket-mismatch recovery inside parseBracketedFieldContent and parseEntry. When an entry contains unbalanced braces, the parser now rewinds to the last valid @EntryType start and skips only the malformed entry instead of discarding the remaining database. This ensures subsequent valid entries are still parsed correctly.

I am opening a draft PR to gather early feedback. I will next focus on strengthening the recovery search heuristic, verifying correct reader rewinding in all scenarios. I plan to continue development and update this PR。

Steps to test

./gradlew :jablib:test --tests "org.jabref.logic.importer.fileformat.BibtexParserTest"

Mandatory checks

  • [x] I own the copyright of the code submitted and I license it under the MIT license
  • [x] I manually tested my changes in running JabRef (always required)
  • [x] I added JUnit tests for changes (if applicable)
  • [/] I added screenshots in the PR description (if change is visible to the user)
  • [/] I described the change in CHANGELOG.md in a way that is understandable for the average user (if change is visible to the user)
  • [/] I checked the user documentation: Is the information available and up to date? If not, I created an issue at https://github.com/JabRef/user-documentation/issues or, even better, I submitted a pull request updating file(s) in https://github.com/JabRef/user-documentation/tree/main/en.

hisunll avatar Dec 01 '25 18:12 hisunll

When I run openRewrite, I get following diff:

diff --git a/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java b/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java
index b2c3142430..229e1e3f05 100644
--- a/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java
+++ b/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java
@@ -375,7 +375,7 @@ public class BibtexParser implements Parser {
                 }

                 int next = peek();
-                LOGGER.info(">>> RECOVERED NEXT CHAR = [" + (char) next + "] @ line " + line);
+                LOGGER.info(">>> RECOVERED NEXT CHAR = [{}] @ line {}", (char) next, line);
                 currentEntryBuffer.setLength(0);
                 dumpTextReadSoFarToString();
             }
diff --git a/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java b/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java
index 2a814cce69..221b919a0b 100644
--- a/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java
+++ b/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java
@@ -2249,7 +2249,7 @@ class BibtexParserTest {
     }

     @Test
-    public void testUnmatchedBracketsDoesNotStopParsing() throws Exception {
+    public void unmatchedBracketsDoesNotStopParsing() throws Exception {
         String entries = """
                 @Article{ok1,
                   title = {AAA},

Not sure how you run openRewrite. I did

.\gg.cmd gradle rewriteRun

gg.cmd is from https://github.com/eirikb/gg.

koppor avatar Dec 08 '25 11:12 koppor

When I run openRewrite, I get following diff:

diff --git a/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java b/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java
index b2c3142430..229e1e3f05 100644
--- a/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java
+++ b/jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java
@@ -375,7 +375,7 @@ public class BibtexParser implements Parser {
                 }

                 int next = peek();
-                LOGGER.info(">>> RECOVERED NEXT CHAR = [" + (char) next + "] @ line " + line);
+                LOGGER.info(">>> RECOVERED NEXT CHAR = [{}] @ line {}", (char) next, line);
                 currentEntryBuffer.setLength(0);
                 dumpTextReadSoFarToString();
             }
diff --git a/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java b/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java
index 2a814cce69..221b919a0b 100644
--- a/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java
+++ b/jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java
@@ -2249,7 +2249,7 @@ class BibtexParserTest {
     }

     @Test
-    public void testUnmatchedBracketsDoesNotStopParsing() throws Exception {
+    public void unmatchedBracketsDoesNotStopParsing() throws Exception {
         String entries = """
                 @Article{ok1,
                   title = {AAA},

Not sure how you run openRewrite. I did

.\gg.cmd gradle rewriteRun

gg.cmd is from https://github.com/eirikb/gg.

Thanks, it works now

hisunll avatar Dec 08 '25 14:12 hisunll