Skip to content
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

Fix NegativeArraySizeException #8270

Merged
merged 5 commits into from
Nov 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve
- We added an option to search the available citation styles by name in the preferences [#8108](https://github.com/JabRef/jabref/issues/8108)
- We added an option to generate bib-entries from ID through a popover in the toolbar. [#4183](https://github.com/JabRef/jabref/issues/4183)
- We added a menu option in the right click menu of the main table tabs to display the library properties. [#6527](https://github.com/JabRef/jabref/issues/6527)
- When a `.bib` file ("library") was saved successfully, a notification is shown

### Changed

Expand Down Expand Up @@ -66,6 +67,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve
- We fixed an issue where importing PDFs resulted in an uncaught exception [#8143](https://github.com/JabRef/jabref/issues/8143)
- We fixed "The library has been modified by another program" showing up when line breaks change [#4877](https://github.com/JabRef/jabref/issues/4877)
- The default directory of the "LaTeX Citations" tab is now the directory of the currently opened database (and not the directory chosen at the last open file dialog or the last database save) [koppor#538](https://github.com/koppor/jabref/issues/538)
- When writing a bib file, the `NegativeArraySizeException` should not occur [#8231](https://github.com/JabRef/jabref/issues/8231) [#8265](https://github.com/JabRef/jabref/issues/8265)
- We fixed an issue where right-clicking on a tab and selecting close will close the focused tab even if it is not the tab we right-clicked [#8193](https://github.com/JabRef/jabref/pull/8193)
- We fixed an issue where selecting a citation style in the preferences would sometimes produce an exception [#7860](https://github.com/JabRef/jabref/issues/7860)
- We fixed an issue where an exception would occur when clicking on a DOI link in the preview pane [#7706](https://github.com/JabRef/jabref/issues/7706)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/DialogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ Optional<ButtonType> showCustomButtonDialogAndWait(Alert.AlertType type, String
<V> Optional<ButtonType> showBackgroundProgressDialogAndWait(String title, String content, StateManager stateManager);

/**
* Notify the user in an non-blocking way (i.e., in form of toast in a snackbar).
* Notify the user in a non-blocking way (i.e., in form of toast in a snackbar).
*
* @param message the message to show.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ private boolean save(Path targetPath, SaveDatabaseMode mode) {
libraryTab.getUndoManager().markUnchanged();
libraryTab.resetChangedProperties();
}
dialogService.notify(Localization.lang("Library saved"));
return success;
} catch (SaveException ex) {
LOGGER.error(String.format("A problem occurred when trying to save the file %s", targetPath), ex);
Expand Down
21 changes: 11 additions & 10 deletions src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, BibWr

Set<Field> written = new HashSet<>();
written.add(InternalField.KEY_FIELD);
int indentation = getLengthOfLongestFieldName(entry);
final int indent = getLengthOfLongestFieldName(entry);

Optional<BibEntryType> type = entryTypesManager.enrich(entry.getType(), bibDatabaseMode);
if (type.isPresent()) {
Expand All @@ -106,7 +106,7 @@ private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, BibWr
.collect(Collectors.toList());

for (Field field : requiredFields) {
writeField(entry, out, field, indentation);
writeField(entry, out, field, indent);
}

// Then optional fields
Expand All @@ -118,7 +118,7 @@ private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, BibWr
.collect(Collectors.toList());

for (Field field : optionalFields) {
writeField(entry, out, field, indentation);
writeField(entry, out, field, indent);
}

written.addAll(requiredFields);
Expand All @@ -131,7 +131,7 @@ private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, BibWr
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Field::getName))));

for (Field field : remainingFields) {
writeField(entry, out, field, indentation);
writeField(entry, out, field, indent);
}

// Finally, end the entry.
Expand All @@ -151,12 +151,13 @@ private void writeKeyField(BibEntry entry, BibWriter out) throws IOException {
* @param field the field
* @throws IOException In case of an IO error
*/
private void writeField(BibEntry entry, BibWriter out, Field field, int indentation) throws IOException {
private void writeField(BibEntry entry, BibWriter out, Field field, int indent) throws IOException {
Optional<String> value = entry.getField(field);
// only write field if it is not empty
// field.ifPresent does not work as an IOException may be thrown
if (value.isPresent() && !value.get().trim().isEmpty()) {
out.write(" " + getFormattedFieldName(field, indentation));
out.write(" ");
out.write(getFormattedFieldName(field, indent));
try {
out.write(fieldWriter.write(field, value.get()));
} catch (InvalidFieldValueException ex) {
Expand All @@ -166,7 +167,7 @@ private void writeField(BibEntry entry, BibWriter out, Field field, int indentat
}
}

private int getLengthOfLongestFieldName(BibEntry entry) {
static int getLengthOfLongestFieldName(BibEntry entry) {
Predicate<Field> isNotCitationKey = field -> !InternalField.KEY_FIELD.equals(field);
return entry.getFields()
.stream()
Expand All @@ -177,7 +178,7 @@ private int getLengthOfLongestFieldName(BibEntry entry) {
}

/**
* Get display version of a entry field.
* Get display version of an entry field.
* <p>
* BibTeX is case-insensitive therefore there is no difference between: howpublished, HOWPUBLISHED, HowPublished, etc.
* <p>
Expand All @@ -188,8 +189,8 @@ private int getLengthOfLongestFieldName(BibEntry entry) {
* @param field The name of the field.
* @return The display version of the field name.
*/
private String getFormattedFieldName(Field field, int intention) {
static String getFormattedFieldName(Field field, int indent) {
String fieldName = field.getName();
return fieldName.toLowerCase(Locale.ROOT) + StringUtil.repeatSpaces(intention - fieldName.length()) + " = ";
return fieldName.toLowerCase(Locale.ROOT) + StringUtil.repeatSpaces(indent - fieldName.length()) + " = ";
}
}
4 changes: 2 additions & 2 deletions src/main/java/org/jabref/model/strings/StringUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public static String join(String[] strings, String separator, int from, int to)
return "";
}

int updatedFrom = Math.max(from, 0);
int updatedFrom = Math.max(0, from);
int updatedTo = Math.min(strings.length, to);

StringBuilder stringBuilder = new StringBuilder();
Expand Down Expand Up @@ -600,7 +600,7 @@ public static String replaceSpecialCharacters(String s) {
* @return String with n spaces
*/
public static String repeatSpaces(int n) {
return repeat(n, ' ');
return repeat(Math.max(0, n), ' ');
}

/**
Expand Down
6 changes: 2 additions & 4 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -753,13 +753,11 @@ Save\ before\ closing=Save before closing

Save\ library=Save library
Save\ library\ as...=Save library as...

Saved\ selected\ to\ '%0'.=Saved selected to '%0'.

Saving=Saving
Saving\ all\ libraries...=Saving all libraries...

Saving\ library=Saving library
Library\ saved=Library saved
Saved\ selected\ to\ '%0'.=Saved selected to '%0'.

Search=Search

Expand Down
85 changes: 84 additions & 1 deletion src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

import org.jabref.logic.exporter.BibWriter;
import org.jabref.logic.importer.ImportFormatPreferences;
Expand All @@ -18,14 +19,19 @@
import org.jabref.model.entry.BibEntryTypesManager;
import org.jabref.model.entry.LinkedFile;
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.FieldFactory;
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.entry.types.EntryTypeFactory;
import org.jabref.model.entry.types.StandardEntryType;
import org.jabref.model.entry.types.UnknownEntryType;
import org.jabref.model.util.DummyFileUpdateMonitor;
import org.jabref.model.util.FileUpdateMonitor;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Answers;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -464,7 +470,7 @@ void monthFieldSpecialSyntax() throws IOException {
Collection<BibEntry> entries = result.getDatabase().getEntries();
BibEntry entry = entries.iterator().next();

// modify month field
// check month field
Set<Field> fields = entry.getFields();
assertTrue(fields.contains(StandardField.MONTH));
assertEquals("#mar#", entry.getField(StandardField.MONTH).get());
Expand All @@ -475,6 +481,51 @@ void monthFieldSpecialSyntax() throws IOException {
assertEquals(bibtexEntry, stringWriter.toString());
}

@Test
void customTypeCanBewritten() throws IOException {
// @formatter:off
String bibtexEntry = "@reference{Broecker1984,\n" +
"title = {International Center of Photography},\n" +
"subtitle = {Encyclopedia of Photography},\n" +
"editor = {Broecker, William L.},\n" +
"date = {1984},\n" +
"eprint = {305515791},\n" +
"eprinttype = {scribd},\n" +
"isbn = {0-517-55271-X},\n" +
"keywords = {g:photography, p:positive, c:silver, m:albumen, c:pigment, m:carbon, g:reference, c:encyclopedia},\n" +
"location = {New York},\n" +
"pagetotal = {678},\n" +
"publisher = {Crown},\n" +
"}\n";
// @formatter:on

// read in bibtex string
ParserResult result = new BibtexParser(importFormatPreferences, fileMonitor).parse(new StringReader(bibtexEntry));
Collection<BibEntry> entries = result.getDatabase().getEntries();
BibEntry entry = entries.iterator().next();

entry.setField(FieldFactory.parseField("location"), "NY");

// write out bibtex string
bibEntryWriter.write(entry, bibWriter, BibDatabaseMode.BIBTEX);

String expected = "@Reference{Broecker1984," + OS.NEWLINE +
" date = {1984}," + OS.NEWLINE +
" editor = {Broecker, William L.}," + OS.NEWLINE +
" eprint = {305515791}," + OS.NEWLINE +
" eprinttype = {scribd}," + OS.NEWLINE +
" isbn = {0-517-55271-X}," + OS.NEWLINE +
" keywords = {g:photography, p:positive, c:silver, m:albumen, c:pigment, m:carbon, g:reference, c:encyclopedia}," + OS.NEWLINE +
" location = {NY}," + OS.NEWLINE +
" pagetotal = {678}," + OS.NEWLINE +
" publisher = {Crown}," + OS.NEWLINE +
" subtitle = {Encyclopedia of Photography}," + OS.NEWLINE +
" title = {International Center of Photography}," + OS.NEWLINE +
"}" + OS.NEWLINE;

assertEquals(expected, stringWriter.toString());
}

@Test
void constantMonthApril() throws Exception {
BibEntry entry = new BibEntry(StandardEntryType.Misc)
Expand Down Expand Up @@ -713,6 +764,38 @@ void testSerializeAll() throws IOException {
// @formatter:on

assertEquals(expected1 + OS.NEWLINE + expected2, output);
}

static Stream<Arguments> testGetFormattedFieldNameData() {
return Stream.of(
Arguments.of(" = ", "", 0),
Arguments.of("a = ", "a", 0),
Arguments.of(" = ", "", 2),
Arguments.of("a = ", "a", 2),
Arguments.of("abc = ", "abc", 2),
Arguments.of("abcdef = ", "abcdef", 6)
);
}

@ParameterizedTest
@MethodSource("testGetFormattedFieldNameData")
void testGetFormattedFieldName(String expected, String fieldName, int indent) {
Field field = FieldFactory.parseField(fieldName);
assertEquals(expected, bibEntryWriter.getFormattedFieldName(field, indent));
}

static Stream<Arguments> testGetLengthOfLongestFieldNameData() {
return Stream.of(
Arguments.of(1, new BibEntry().withField(FieldFactory.parseField("t"), "t")),
Arguments.of(5, new BibEntry(EntryTypeFactory.parse("reference"))
.withCitationKey("Broecker1984")
.withField(StandardField.TITLE, "International Center of Photography}"))
);
}

@ParameterizedTest
@MethodSource("testGetLengthOfLongestFieldNameData")
void testGetLengthOfLongestFieldName(int expected, BibEntry entry) {
assertEquals(expected, bibEntryWriter.getLengthOfLongestFieldName(entry));
}
}
18 changes: 13 additions & 5 deletions src/test/java/org/jabref/model/strings/StringUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,19 @@ void replaceSpecialCharactersWithNonNormalizedUnicode() {
assertEquals("Modele", StringUtil.replaceSpecialCharacters("Modèle"));
}

@Test
void testRepeatSpaces() {
assertEquals("", StringUtil.repeatSpaces(0));
assertEquals(" ", StringUtil.repeatSpaces(1));
assertEquals(" ", StringUtil.repeatSpaces(7));
static Stream<Arguments> testRepeatSpacesData() {
return Stream.of(
Arguments.of("", -1),
Arguments.of("", 0),
Arguments.of(" ", 1),
Arguments.of(" ", 7)
);
}

@ParameterizedTest
@MethodSource("testRepeatSpacesData")
void testRepeatSpaces(String result, int count) {
assertEquals(result, StringUtil.repeatSpaces(count));
}

@Test
Expand Down