Skip to content

Commit

Permalink
Allow trailing whitespace document split marker
Browse files Browse the repository at this point in the history
Refine `OriginTrackedPropertiesLoader` document split detection to be
more lenient if there is trailing whitespace.

Closes spring-projectsgh-23399
  • Loading branch information
philwebb committed Sep 17, 2020
1 parent 90483d3 commit 8b8d5cc
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ class OriginTrackedPropertiesLoader {
}

/**
* Load {@code .properties} data and return a map of {@code String} ->
* {@link OriginTrackedValue}.
* Load {@code .properties} data and return a list of documents.
* @return the loaded properties
* @throws IOException on read error
*/
Expand All @@ -79,7 +78,7 @@ List<Document> load(boolean expandLists) throws IOException {
try (CharacterReader reader = new CharacterReader(this.resource)) {
StringBuilder buffer = new StringBuilder();
while (reader.read()) {
if (reader.getCharacter() == '#') {
if (reader.isPoundCharacter()) {
if (isNewDocument(reader)) {
if (!document.isEmpty()) {
result.add(document);
Expand Down Expand Up @@ -150,12 +149,13 @@ private OriginTrackedValue loadValue(StringBuilder buffer, CharacterReader reade
}

boolean isNewDocument(CharacterReader reader) throws IOException {
boolean result = reader.isPoundCharacter();
boolean result = reader.getLocation().getColumn() == 0 && reader.isPoundCharacter();
result = result && readAndExpect(reader, reader::isHyphenCharacter);
result = result && readAndExpect(reader, reader::isHyphenCharacter);
result = result && readAndExpect(reader, reader::isHyphenCharacter);
result = result && readAndExpect(reader, reader::isEndOfLine);
return result;
reader.read();
reader.skipWhitespace();
return result && reader.isEndOfLine();
}

private boolean readAndExpect(CharacterReader reader, BooleanSupplier check) throws IOException {
Expand Down Expand Up @@ -198,7 +198,7 @@ boolean read(boolean wrappedLine) throws IOException {
this.character = this.reader.read();
this.columnNumber++;
if (this.columnNumber == 0) {
skipLeadingWhitespace();
skipWhitespace();
if (!wrappedLine) {
if (this.character == '!') {
skipComment();
Expand All @@ -215,7 +215,7 @@ else if (this.character == '\n') {
return !isEndOfFile();
}

private void skipLeadingWhitespace() throws IOException {
private void skipWhitespace() throws IOException {
while (isWhiteSpace()) {
this.character = this.reader.read();
this.columnNumber++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.boot.env;

import java.io.IOException;
import java.util.List;
import java.util.Properties;

Expand All @@ -25,6 +26,7 @@
import org.springframework.boot.env.OriginTrackedPropertiesLoader.Document;
import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.boot.origin.TextResourceOrigin;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

Expand Down Expand Up @@ -180,6 +182,34 @@ void getImmediateMultiline() {
assertThat(getLocation(value)).isEqualTo("32:1");
}

@Test
void loadWhenMultiDocumentWithoutWhitespaceLoadsMultiDoc() throws IOException {
String content = "a=a\n#---\nb=b";
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
assertThat(loaded).hasSize(2);
}

@Test
void loadWhenMultiDocumentWithLeadingWhitespaceLoadsSingleDoc() throws IOException {
String content = "a=a\n \t#---\nb=b";
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
assertThat(loaded).hasSize(1);
}

@Test
void loadWhenMultiDocumentWithTrailingWhitespaceLoadsMultiDoc() throws IOException {
String content = "a=a\n#--- \t \nb=b";
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
assertThat(loaded).hasSize(2);
}

@Test
void loadWhenMultiDocumentWithTrailingCharsLoadsSingleDoc() throws IOException {
String content = "a=a\n#--- \tcomment\nb=b";
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
assertThat(loaded).hasSize(1);
}

@Test
void getPropertyWithWhitespaceAfterKey() {
OriginTrackedValue value = getFromFirst("bar");
Expand Down

0 comments on commit 8b8d5cc

Please sign in to comment.