@@ -60,33 +60,41 @@ public DotenvParser(final DotenvReader reader, final boolean throwIfMissing, fin
60
60
*/
61
61
public List <DotenvEntry > parse () throws DotenvException {
62
62
final var lines = lines ();
63
- final var entries = new ArrayList <DotenvEntry >(lines .size ());
63
+ final var entries = new ArrayList <DotenvEntry >();
64
+
65
+ var currentEntry = "" ;
64
66
for (final var line : lines ) {
65
- addNewEntry ( entries , line . trim ());
66
- }
67
+ if ( currentEntry . equals ( "" ) && ( isWhiteSpace . test ( line ) || isComment . test ( line ) || isBlank ( line )))
68
+ continue ;
67
69
68
- return entries ;
69
- }
70
+ currentEntry += line ;
70
71
71
- private void addNewEntry (final List <DotenvEntry > entries , final String line ) {
72
- if (isWhiteSpace .test (line ) || isComment .test (line ) || isBlank (line ))
73
- return ;
72
+ final var entry = parseLine .apply (currentEntry );
73
+ if (entry == null ) {
74
+ if (throwIfMalformed )
75
+ throw new DotenvException ("Malformed entry " + currentEntry );
76
+ currentEntry = "" ;
77
+ continue ;
78
+ }
74
79
75
- final var entry = parseLine .apply (line );
76
- if (entry == null ) {
77
- if (throwIfMalformed )
78
- throw new DotenvException ("Malformed entry " + line );
79
- return ;
80
+ var value = entry .getValue ();
81
+ if (QuotedStringValidator .startsWithQuote (value ) && !QuotedStringValidator .endsWithQuote (value )) {
82
+ currentEntry += "\n " ;
83
+ continue ;
84
+ }
85
+ if (!QuotedStringValidator .isValid (entry .getValue ())) {
86
+ if (throwIfMalformed )
87
+ throw new DotenvException ("Malformed entry, unmatched quotes " + line );
88
+ currentEntry = "" ;
89
+ continue ;
90
+ }
91
+ final var key = entry .getKey ();
92
+ value = QuotedStringValidator .stripQuotes (entry .getValue ());
93
+ entries .add (new DotenvEntry (key , value ));
94
+ currentEntry = "" ;
80
95
}
81
96
82
- if (!QuotedStringValidator .isValid (entry .getValue ())) {
83
- if (throwIfMalformed )
84
- throw new DotenvException ("Malformed entry, unmatched quotes " + line );
85
- return ;
86
- }
87
- final var key = entry .getKey ();
88
- final var value = QuotedStringValidator .stripQuotes (entry .getValue ());
89
- entries .add (new DotenvEntry (key , value ));
97
+ return entries ;
90
98
}
91
99
92
100
private List <String > lines () throws DotenvException {
@@ -123,14 +131,17 @@ private static boolean isBlank(String s) {
123
131
private static class QuotedStringValidator {
124
132
private static boolean isValid (String input ) {
125
133
final var s = input .trim ();
126
- if (!s .startsWith ("\" " ) && !s .endsWith ("\" " )) {
127
- // not quoted, its valid
134
+ if (isNotQuoted (s )) {
128
135
return true ;
129
136
}
130
- if (input .length () == 1 || !(s .startsWith ("\" " ) && s .endsWith ("\" " ))) {
131
- // doesn't start and end with quote
137
+ if (doesNotStartAndEndWithQuote (s )) {
132
138
return false ;
133
139
}
140
+
141
+ return !hasUnescapedQuote (s ); // No unescaped quotes found
142
+ }
143
+ private static boolean hasUnescapedQuote (final String s ) {
144
+ boolean hasUnescapedQuote = false ;
134
145
// remove start end quote
135
146
var content = s .substring (1 , s .length () - 1 );
136
147
var quotePattern = Pattern .compile ("\" " );
@@ -141,10 +152,22 @@ private static boolean isValid(String input) {
141
152
int quoteIndex = matcher .start ();
142
153
// Check if the quote is escaped
143
154
if (quoteIndex == 0 || content .charAt (quoteIndex - 1 ) != '\\' ) {
144
- return false ; // unescaped quote found
155
+ hasUnescapedQuote = true ; // unescaped quote found
145
156
}
146
157
}
147
- return true ; // No unescaped quotes found
158
+ return hasUnescapedQuote ;
159
+ }
160
+ private static boolean doesNotStartAndEndWithQuote (final String s ) {
161
+ return s .length () == 1 || !(startsWithQuote (s ) && endsWithQuote (s ));
162
+ }
163
+ private static boolean endsWithQuote (final String s ) {
164
+ return s .endsWith ("\" " );
165
+ }
166
+ private static boolean startsWithQuote (final String s ) {
167
+ return s .startsWith ("\" " );
168
+ }
169
+ private static boolean isNotQuoted (final String s ) {
170
+ return !startsWithQuote (s ) && !endsWithQuote (s );
148
171
}
149
172
private static String stripQuotes (String input ) {
150
173
var tr = input .trim ();
0 commit comments