Skip to content

Fix month checker regex#15678

Merged
Siedlerchr merged 10 commits into
JabRef:mainfrom
ridsch:fix-month-checker-regex
May 6, 2026
Merged

Fix month checker regex#15678
Siedlerchr merged 10 commits into
JabRef:mainfrom
ridsch:fix-month-checker-regex

Conversation

@ridsch

@ridsch ridsch commented May 4, 2026

Copy link
Copy Markdown
Contributor

Related issues and pull requests

Closes #15577
#15577

PR Description

This PR updates the MonthChecker validation logic by adding start (^) and end ($) anchors to the underlying regular expressions. This change enforces exact string matching for month values, ensuring that only valid integers (1-12) or normalized BibTeX strings are accepted while preventing malformed partial matches from passing the validation layer.

Steps to test

  1. Open JabRef and create a new entry (e.g., an Article).
  2. Locate a field that utilizes the Month validator (such as the Month field in the entry editor or the String Editor).
  3. Enter a value that contains a valid month name but is incorrectly formatted (January123 or #jan#invalid).
  4. Observe that the validator now correctly flags these as errors.
  5. Enter a valid month (10 or #jan#) and verify it is still accepted.
AuthorScreenshot15577

AI Disclosure

I utilized Google Gemini to help troubleshoot local Gradle build environment issues and assist in drafting JUnit test structure for this PR. All logic was manually verified and tested against the JabRef contribution guidelines.

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • [/] I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • [/] I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add regex anchors to enforce exact month validation

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Add regex anchors (^ and $) to MonthChecker patterns
• Enforce exact string matching for month validation
• Prevent malformed partial matches from passing validation
• Update CHANGELOG.md documenting the fix
Diagram
flowchart LR
  A["MonthChecker Regex Patterns"] -->|Add anchors ^ and $| B["Exact String Matching"]
  B -->|Reject| C["Partial Matches"]
  B -->|Accept| D["Valid Months"]
Loading

Grey Divider

File Changes

1. jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java 🐞 Bug fix +2/-2

Add regex anchors for exact month matching

• Updated ONLY_AN_INTEGER regex pattern from [1-9]|10|11|12 to ^([1-9]|10|11|12)$
• Updated MONTH_NORMALIZED regex pattern to include start and end anchors
• Enforces exact matching for month values (1-12 or normalized BibTeX strings)
• Prevents validation bypass through malformed partial matches like "January123"

jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java


2. CHANGELOG.md 📝 Documentation +1/-0

Document MonthChecker validation fix

• Added entry documenting the MonthChecker fix for issue #15577
• Describes the fix as preventing partial matches for month values

CHANGELOG.md


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Missing partial month tests ✓ Resolved 📎 Requirement gap ≡ Correctness
Description
Month validation behavior was changed, but no regression tests were added to ensure mixed/partial
values like 1abc or #jan# trailing are rejected. This risks reintroducing the original bug
without automated detection.
Code

jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[R16-20]

+    private static final Predicate<String> ONLY_AN_INTEGER = Pattern.compile("^([1-9]|10|11|12)$")
                                                             .asPredicate();
private static final Predicate<String> MONTH_NORMALIZED = Pattern
-            .compile("#jan#|#feb#|#mar#|#apr#|#may#|#jun#|#jul#|#aug#|#sep#|#oct#|#nov#|#dec#")
+            .compile("^(#jan#|#feb#|#mar#|#apr#|#may#|#jun#|#jul#|#aug#|#sep#|#oct#|#nov#|#dec#)$")
     .asPredicate();
Evidence
The checklist requires adding/adjusting unit tests for the previously accepted invalid inputs. The
production code was modified to tighten regex matching, but the existing MonthCheckerTest does not
include assertions for the required regression cases (e.g., 1abc, #jan# trailing).

Add regression tests to reject mixed/partial month values in MonthChecker
AGENTS.md
AGENTS.md
jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[16-20]
jablib/src/test/java/org/jabref/logic/integrity/MonthCheckerTest.java[31-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`MonthChecker` behavior was tightened, but regression tests for the originally reported partial/mixed inputs are missing.
## Issue Context
Compliance requires tests that fail for values that previously passed due to partial regex matching (e.g., `1abc`, `#jan# trailing`).
## Fix Focus Areas
- jablib/src/test/java/org/jabref/logic/integrity/MonthCheckerTest.java[31-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Rejects zero-padded months ✓ Resolved 🐞 Bug ≡ Correctness
Description
In BibLaTeX mode, MonthChecker now rejects month integers with a leading zero (e.g.,
"01"/"02"/"09"), returning “should be an integer or normalized”. The codebase already parses and
produces these values, so integrity checks/validation can start flagging existing entries as invalid
after this change.
Code

jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[R16-17]

+    private static final Predicate<String> ONLY_AN_INTEGER = Pattern.compile("^([1-9]|10|11|12)$")
                                                             .asPredicate();
Evidence
MonthChecker validates BibLaTeX months using ONLY_AN_INTEGER.test(value.trim()), and the new
pattern only matches 1–12 without a leading zero. However, Month.parse explicitly documents
support for “Single and Double Digit months … (01 to 12)”, and tests/importers construct entries
with zero-padded month strings like "02" and "09"; these will now fail MonthChecker in BibLaTeX
mode.

jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[16-48]
jablib/src/main/java/org/jabref/model/entry/Month.java[64-97]
jablib/src/test/java/org/jabref/logic/importer/fetcher/ResearchGateTest.java[87-121]
jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java[2185-2205]
jablib/src/main/java/org/jabref/logic/integrity/FieldCheckers.java[45-47]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`MonthChecker`'s BibLaTeX integer validation regex only matches `1`–`12` without a leading zero. This causes values like `"01"`, `"02"`, `"09"` (which the codebase parses/produces) to be treated as invalid.
### Issue Context
`Month.parse` explicitly supports “01 to 12”, and multiple tests construct entries with `StandardField.MONTH` set to zero-padded values.
### Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[16-20]
### Suggested change
- Update the integer regex to accept an optional leading zero for 1–9, e.g.:
- `^(0?[1-9]|1[0-2])$`
- Add/extend unit tests (e.g., `MonthCheckerTest`) to cover:
- Accept: `01`, `02`, `09`, `10`, `12`
- Reject: `00`, `13`, `01abc`, `#jan# trailing`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Changelog uses internal classname ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The new CHANGELOG entry references the internal class name MonthChecker and deviates from the
surrounding end-user-focused phrasing style. This reduces readability and consistency for end users.
Code

CHANGELOG.md[107]

+- Fixed issue where MonthChecker allowed partial matches for month values. [#15577](https://github.com/JabRef/jabref/pull/15675)
Evidence
The checklist requires CHANGELOG entries to be end-user focused and professionally
worded/consistent. The added bullet explicitly mentions an internal validator class name rather than
describing the user-visible effect in user terms.

AGENTS.md
CHANGELOG.md[107-107]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
CHANGELOG entry is a bit too implementation-specific and inconsistent in style.
## Issue Context
Nearby entries use end-user phrasing (e.g., "We fixed...") and generally avoid internal class names.
## Fix Focus Areas
- CHANGELOG.md[107-107]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Predicate intent unclear 🐞 Bug ⚙ Maintainability
Description
MonthChecker still uses Pattern.asPredicate() for validation, so full-string matching
correctness relies on regex anchors rather than the predicate’s match semantics. This makes the
intent less explicit and increases the chance of a future regression if the pattern is edited.
Code

jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[R16-20]

+    private static final Predicate<String> ONLY_AN_INTEGER = Pattern.compile("^([1-9]|10|11|12)$")
                                                             .asPredicate();
private static final Predicate<String> MONTH_NORMALIZED = Pattern
-            .compile("#jan#|#feb#|#mar#|#apr#|#may#|#jun#|#jul#|#aug#|#sep#|#oct#|#nov#|#dec#")
+            .compile("^(#jan#|#feb#|#mar#|#apr#|#may#|#jun#|#jul#|#aug#|#sep#|#oct#|#nov#|#dec#)$")
     .asPredicate();
Evidence
Both month validators are built using .asPredicate() even though the surrounding logic is doing
strict whole-field validation (as shown by the anchors and value.trim() usage). Elsewhere, strict
month-format checks are implemented using full-string matching (String.matches(...)), which is
more self-documenting for this use case.

jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[16-49]
jablib/src/main/java/org/jabref/model/entry/Month.java[191-205]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`MonthChecker` uses `Pattern.asPredicate()` for validations that are intended to be whole-string matches.
### Issue Context
The current behavior is correct only because the regexes are anchored. Using `asMatchPredicate()` encodes the intent (“entire string must match”) directly.
### Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java[16-20]
### Suggested change
- Replace `.asPredicate()` with `.asMatchPredicate()`.
- Optionally drop the `^...$` anchors once using `asMatchPredicate()` (or keep them, but avoid relying on them for semantics).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/integrity/MonthChecker.java Outdated
Comment thread CHANGELOG.md Outdated
@pluto-han

Copy link
Copy Markdown
Collaborator

Please address Qodo comments

@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels May 5, 2026
@subhramit

Copy link
Copy Markdown
Member

If possible, please also add a test.

@ridsch

ridsch commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

updated the regex to allow zero-padded months (01-09) as suggested by Qodo and added regression tests in MonthCheckerTest.java

@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: no-bot-comments labels May 5, 2026
Comment thread jablib/src/test/java/org/jabref/logic/integrity/MonthCheckerTest.java Outdated
@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels May 5, 2026

@Test
void checkValueAcceptsZeroPaddedMonths() {
// Confirms that the optional zero (0?) in the regex works for Biblatex mode

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these comments.


@Test
void checkValueDoesNotAcceptPartialMatches() {
assertEquals(Optional.of(Localization.lang("should be an integer or normalized")),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Revert the format change

  2. Localization.lang is not necessary

@pluto-han

Copy link
Copy Markdown
Collaborator

Please disclose AI uasge in this PR.

@ridsch

ridsch commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

Added AI Disclosure to PR description.

@pluto-han

Copy link
Copy Markdown
Collaborator

LGTM

@Siedlerchr Siedlerchr added this pull request to the merge queue May 6, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label May 6, 2026
Merged via the queue into JabRef:main with commit e0c3f92 May 6, 2026
54 checks passed
Siedlerchr added a commit to pluto-han/jabref that referenced this pull request May 11, 2026
* upstream/main: (21 commits)
  chore(deps): update dependency com.konghq:unirest-modules-gson to v4.10.0 (JabRef#15715)
  Add manual tests (JabRef#15351)
  Refactored the comments for UnlinkedFilesCrawler (JabRef#15709)
  Replace inline styles with CSS classes (JabRef#15694)
  add test case for multiple authors in csl citaiton (JabRef#15707)
  fix invalid desktop file for linux (JabRef#15702)
  Change FileKeystore and Folder fields to disable/enable (JabRef#15685)
  Chore(deps): Bump org.openrewrite.recipe:rewrite-recipe-bom from 3.30.0 to 3.30.1 (JabRef#15696)
  New Crowdin updates (JabRef#15693)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (JabRef#15698)
  Chore(deps): Bump org.apache.logging.log4j:log4j-to-slf4j in /versions (JabRef#15700)
  chore(deps): update dependency org.apache.logging.log4j:log4j-to-slf4j to v2.26.0 (JabRef#15699)
  Chore(deps): Bump org.openrewrite.rewrite from 7.32.1 to 7.32.2 (JabRef#15697)
  Chore(deps): Bump jablib/src/main/resources/csl-locales (JabRef#15689)
  Fix month checker regex (JabRef#15678)
  Chore(deps): Bump com.dlsc.gemsfx:gemsfx in /versions (JabRef#15692)
  Chore(deps): Bump org.hisp.dhis:json-tree in /versions (JabRef#15691)
  Chore(deps): Bump jablib/src/main/resources/csl-styles (JabRef#15690)
  New Crowdin updates (JabRef#15687)
  Chore(deps): Bump com.konghq:unirest-java-core in /versions (JabRef#15683)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: MonthChecker Uses Partial Regex Match — Invalid Month Values Pass Validation

4 participants