diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index cb49dce329a..7c2c2703f0d 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -41,6 +41,9 @@ Bug Fixes This causes assertion errors and potentially broken field attributes in the IndexWriter when IndexWriter#deleteAll is called while actively indexing. (Simon Willnauer) +* LUCENE-8804: Forbid calls to putAttribute on frozen FieldType instances. + (Vamshi Vijay Nakkirtha via Adrien Grand) + Improvements * LUCENE-7840: Non-scoring BooleanQuery now removes SHOULD clauses before building the scorer supplier diff --git a/lucene/core/src/java/org/apache/lucene/document/FieldType.java b/lucene/core/src/java/org/apache/lucene/document/FieldType.java index b450eee385e..8dd802c6970 100644 --- a/lucene/core/src/java/org/apache/lucene/document/FieldType.java +++ b/lucene/core/src/java/org/apache/lucene/document/FieldType.java @@ -361,6 +361,7 @@ public class FieldType implements IndexableFieldType { * @lucene.experimental */ public String putAttribute(String key, String value) { + checkIfFrozen(); if (attributes == null) { attributes = new HashMap<>(); } diff --git a/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java b/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java index b770e62cb52..8237a4f4be8 100644 --- a/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java +++ b/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java @@ -72,6 +72,27 @@ public class TestFieldType extends LuceneTestCase { assertEquals("pointDataDimensionCount=1,pointIndexDimensionCount=1,pointNumBytes=4", ft.toString()); } + /** + * FieldType's attribute map should not be modifiable/add after freeze + */ + public void testAttributeMapFrozen() { + FieldType ft = new FieldType(); + ft.putAttribute("dummy", "d"); + ft.freeze(); + expectThrows(IllegalStateException.class, () -> ft.putAttribute("dummy", "a")); + } + + /** + * FieldType's attribute map can be changed if not frozen + */ + public void testAttributeMapNotFrozen() { + FieldType ft = new FieldType(); + ft.putAttribute("dummy", "d"); + ft.putAttribute("dummy", "a"); + assertEquals(ft.getAttributes().size(), 1); + assertEquals(ft.getAttributes().get("dummy"), "a"); + } + private static Object randomValue(Class clazz) { if (clazz.isEnum()) { return RandomPicks.randomFrom(random(), clazz.getEnumConstants());