|
57 | 57 | * DOM and XML accessibility and comfort functions. |
58 | 58 | * |
59 | 59 | * @implNote |
60 | | - * Following system properties affect XML formatting: |
| 60 | + * The following system properties affect XML formatting: |
61 | 61 | * <ul> |
62 | 62 | * <li>{@systemProperty org.apache.xml.security.ignoreLineBreaks} - ignores all line breaks, |
63 | 63 | * making a single-line document. Overrides all other formatting options. Default: false</li> |
|
66 | 66 | * <li>{@systemProperty org.apache.xml.security.base64.lineSeparator} - Sets the line separator sequence in base64Binary values. |
67 | 67 | * Possible values: crlf, lf. Default: crlf</li> |
68 | 68 | * <li>{@systemProperty org.apache.xml.security.base64.lineLength} - Sets maximum line length in base64Binary values. |
69 | | - * The value is rounded down to nearest multiple of 4. Values less than 4 are ignored. Default: 76</li> |
| 69 | + * The value is rounded down to the nearest multiple of 4. Values less than 4 are ignored. Default: 76</li> |
70 | 70 | * </ul> |
71 | 71 | */ |
72 | 72 | public final class XMLUtils { |
73 | 73 |
|
74 | 74 | private static final Logger LOG = System.getLogger(XMLUtils.class.getName()); |
75 | 75 |
|
76 | 76 | private static final String IGNORE_LINE_BREAKS_PROP = "org.apache.xml.security.ignoreLineBreaks"; |
77 | | - private static final String BASE64_IGNORE_LINE_BREAKS_PROP = "org.apache.xml.security.base64.ignoreLineBreaks"; |
78 | | - private static final String BASE64_LINE_SEPARATOR_PROP = "org.apache.xml.security.base64.lineSeparator"; |
79 | | - private static final String BASE64_LINE_LENGTH_PROP = "org.apache.xml.security.base64.lineLength"; |
80 | 77 |
|
81 | 78 | private static boolean ignoreLineBreaks = |
82 | 79 | AccessController.doPrivileged( |
83 | 80 | (PrivilegedAction<Boolean>) () -> Boolean.getBoolean(IGNORE_LINE_BREAKS_PROP)); |
84 | 81 |
|
85 | 82 | private static Base64FormattingOptions base64Formatting = |
86 | | - AccessController.doPrivileged((PrivilegedAction<Base64FormattingOptions>) () -> { |
87 | | - Base64FormattingOptions options = new Base64FormattingOptions(); |
88 | | - options.setIgnoreLineBreaks(Boolean.getBoolean(BASE64_IGNORE_LINE_BREAKS_PROP)); |
89 | | - |
90 | | - String lineSeparator = System.getProperty(BASE64_LINE_SEPARATOR_PROP); |
91 | | - if (lineSeparator != null) { |
92 | | - try { |
93 | | - options.setLineSeparator(Base64LineSeparator.valueOf(lineSeparator.toUpperCase())); |
94 | | - } catch (IllegalArgumentException e) { |
95 | | - LOG.log(Level.WARNING, "Illegal value of {0} property ignored: {1}", |
96 | | - BASE64_LINE_SEPARATOR_PROP, lineSeparator); |
97 | | - } |
98 | | - } |
99 | | - |
100 | | - Integer lineLength = Integer.getInteger(BASE64_LINE_LENGTH_PROP); |
101 | | - if (lineLength != null && lineLength >= 4) { |
102 | | - options.setLineLength(lineLength); |
103 | | - } else if (lineLength != null) { |
104 | | - LOG.log(Level.WARNING, "Illegal value of {0} property ignored: {1}", |
105 | | - BASE64_LINE_LENGTH_PROP, lineLength); |
106 | | - } |
107 | | - |
108 | | - return options; |
109 | | - }); |
| 83 | + AccessController.doPrivileged( |
| 84 | + (PrivilegedAction<Base64FormattingOptions>) () -> new Base64FormattingOptions()); |
110 | 85 |
|
111 | 86 | private static Base64.Encoder base64Encoder = (ignoreLineBreaks || base64Formatting.isIgnoreLineBreaks()) ? |
112 | 87 | Base64.getEncoder() : |
@@ -1152,33 +1127,71 @@ public static byte[] getBytes(BigInteger big, int bitlen) { |
1152 | 1127 | * Aggregates formatting options for base64Binary values. |
1153 | 1128 | */ |
1154 | 1129 | static class Base64FormattingOptions { |
| 1130 | + private static final String BASE64_IGNORE_LINE_BREAKS_PROP = "org.apache.xml.security.base64.ignoreLineBreaks"; |
| 1131 | + private static final String BASE64_LINE_SEPARATOR_PROP = "org.apache.xml.security.base64.lineSeparator"; |
| 1132 | + private static final String BASE64_LINE_LENGTH_PROP = "org.apache.xml.security.base64.lineLength"; |
| 1133 | + |
1155 | 1134 | private boolean ignoreLineBreaks = false; |
1156 | 1135 | private Base64LineSeparator lineSeparator = Base64LineSeparator.CRLF; |
1157 | 1136 | private int lineLength = 76; |
1158 | 1137 |
|
1159 | | - public boolean isIgnoreLineBreaks() { |
1160 | | - return ignoreLineBreaks; |
| 1138 | + /** |
| 1139 | + * Creates new formatting options by reading system properties. |
| 1140 | + */ |
| 1141 | + public Base64FormattingOptions() { |
| 1142 | + String ignoreLineBreaksProp = System.getProperty(BASE64_IGNORE_LINE_BREAKS_PROP); |
| 1143 | + ignoreLineBreaks = Boolean.parseBoolean(ignoreLineBreaksProp); |
| 1144 | + if (XMLUtils.ignoreLineBreaks && ignoreLineBreaksProp != null && !ignoreLineBreaks) { |
| 1145 | + LOG.log(Level.WARNING, "{0} property takes precedence over {1}, line breaks will be ignored", |
| 1146 | + IGNORE_LINE_BREAKS_PROP, BASE64_IGNORE_LINE_BREAKS_PROP); |
| 1147 | + } |
| 1148 | + |
| 1149 | + String lineSeparatorProp = System.getProperty(BASE64_LINE_SEPARATOR_PROP); |
| 1150 | + if (lineSeparatorProp != null) { |
| 1151 | + try { |
| 1152 | + lineSeparator = Base64LineSeparator.valueOf(lineSeparatorProp.toUpperCase()); |
| 1153 | + if (XMLUtils.ignoreLineBreaks || ignoreLineBreaks) { |
| 1154 | + LOG.log(Level.WARNING, "Property {0} has no effect since line breaks are ignored", |
| 1155 | + BASE64_LINE_SEPARATOR_PROP); |
| 1156 | + } |
| 1157 | + } catch (IllegalArgumentException e) { |
| 1158 | + LOG.log(Level.WARNING, "Illegal value of {0} property is ignored: {1}", |
| 1159 | + BASE64_LINE_SEPARATOR_PROP, lineSeparatorProp); |
| 1160 | + } |
| 1161 | + } |
| 1162 | + |
| 1163 | + String lineLengthProp = System.getProperty(BASE64_LINE_LENGTH_PROP); |
| 1164 | + if (lineLengthProp != null) { |
| 1165 | + try { |
| 1166 | + int lineLength = Integer.parseInt(lineLengthProp); |
| 1167 | + if (lineLength >= 4) { |
| 1168 | + this.lineLength = lineLength; |
| 1169 | + if (XMLUtils.ignoreLineBreaks || ignoreLineBreaks) { |
| 1170 | + LOG.log(Level.WARNING, "Property {0} has no effect since line breaks are ignored", |
| 1171 | + BASE64_LINE_LENGTH_PROP); |
| 1172 | + } |
| 1173 | + } else { |
| 1174 | + LOG.log(Level.WARNING, "Illegal value of {0} property is ignored: {1}", |
| 1175 | + BASE64_LINE_LENGTH_PROP, lineLengthProp); |
| 1176 | + } |
| 1177 | + } catch (NumberFormatException e) { |
| 1178 | + LOG.log(Level.WARNING, "Illegal value of {0} property is ignored: {1}", |
| 1179 | + BASE64_LINE_LENGTH_PROP, lineLengthProp); |
| 1180 | + } |
| 1181 | + } |
1161 | 1182 | } |
1162 | 1183 |
|
1163 | | - public void setIgnoreLineBreaks(boolean ignoreLineBreaks) { |
1164 | | - this.ignoreLineBreaks = ignoreLineBreaks; |
| 1184 | + public boolean isIgnoreLineBreaks() { |
| 1185 | + return ignoreLineBreaks; |
1165 | 1186 | } |
1166 | 1187 |
|
1167 | 1188 | public Base64LineSeparator getLineSeparator() { |
1168 | 1189 | return lineSeparator; |
1169 | 1190 | } |
1170 | 1191 |
|
1171 | | - public void setLineSeparator(Base64LineSeparator lineSeparator) { |
1172 | | - this.lineSeparator = lineSeparator; |
1173 | | - } |
1174 | | - |
1175 | 1192 | public int getLineLength() { |
1176 | 1193 | return lineLength; |
1177 | 1194 | } |
1178 | | - |
1179 | | - public void setLineLength(int lineLength) { |
1180 | | - this.lineLength = lineLength; |
1181 | | - } |
1182 | 1195 | } |
1183 | 1196 |
|
1184 | 1197 | enum Base64LineSeparator { |
|
0 commit comments