@@ -858,10 +858,18 @@ private void check(String directive) {
858
858
// serviceMap changed since last call to getServices()
859
859
private volatile transient boolean servicesChanged ;
860
860
861
+ // Map<String,String> used to keep track of legacy registration
862
+ private transient Map <String ,String > legacyStrings ;
863
+
861
864
// Map<ServiceKey,Service>
862
865
// used for services added via putService(), initialized on demand
863
866
private transient Map <ServiceKey ,Service > serviceMap ;
864
867
868
+ // For backward compatibility, the registration ordering of
869
+ // SecureRandom (RNG) algorithms needs to be preserved for
870
+ // "new SecureRandom()" calls when this provider is used
871
+ private transient Set <Service > prngServices ;
872
+
865
873
// Map<ServiceKey,Service>
866
874
// used for services added via legacy methods, init on demand
867
875
private transient Map <ServiceKey ,Service > legacyMap ;
@@ -913,12 +921,18 @@ private void readObject(ObjectInputStream in)
913
921
putAll (copy );
914
922
}
915
923
916
- private static boolean isProviderInfo (Object key ) {
924
+ // check whether to update 'legacyString' with the specified key
925
+ private boolean checkLegacy (Object key ) {
917
926
String keyString = (String )key ;
918
927
if (keyString .startsWith ("Provider." )) {
919
- return true ;
928
+ return false ;
929
+ }
930
+
931
+ legacyChanged = true ;
932
+ if (legacyStrings == null ) {
933
+ legacyStrings = new LinkedHashMap <>();
920
934
}
921
- return false ;
935
+ return true ;
922
936
}
923
937
924
938
/**
@@ -934,41 +948,42 @@ private void implPutAll(Map<?,?> t) {
934
948
935
949
private Object implRemove (Object key ) {
936
950
if (key instanceof String ) {
937
- if (isProviderInfo (key )) {
951
+ if (! checkLegacy (key )) {
938
952
return null ;
939
953
}
940
- legacyChanged = true ;
954
+ legacyStrings . remove (( String ) key ) ;
941
955
}
942
956
return super .remove (key );
943
957
}
944
958
945
959
private boolean implRemove (Object key , Object value ) {
946
960
if (key instanceof String && value instanceof String ) {
947
- if (isProviderInfo (key )) {
961
+ if (! checkLegacy (key )) {
948
962
return false ;
949
963
}
950
- legacyChanged = true ;
964
+ legacyStrings . remove (( String ) key , ( String ) value ) ;
951
965
}
952
966
return super .remove (key , value );
953
967
}
954
968
955
969
private boolean implReplace (Object key , Object oldValue , Object newValue ) {
956
970
if ((key instanceof String ) && (oldValue instanceof String ) &&
957
971
(newValue instanceof String )) {
958
- if (isProviderInfo (key )) {
972
+ if (! checkLegacy (key )) {
959
973
return false ;
960
974
}
961
- legacyChanged = true ;
975
+ legacyStrings .replace ((String )key , (String )oldValue ,
976
+ (String )newValue );
962
977
}
963
978
return super .replace (key , oldValue , newValue );
964
979
}
965
980
966
981
private Object implReplace (Object key , Object value ) {
967
982
if ((key instanceof String ) && (value instanceof String )) {
968
- if (isProviderInfo (key )) {
983
+ if (! checkLegacy (key )) {
969
984
return null ;
970
985
}
971
- legacyChanged = true ;
986
+ legacyStrings . replace (( String ) key , ( String ) value ) ;
972
987
}
973
988
return super .replace (key , value );
974
989
}
@@ -977,17 +992,26 @@ private Object implReplace(Object key, Object value) {
977
992
private void implReplaceAll (BiFunction <? super Object , ? super Object ,
978
993
? extends Object > function ) {
979
994
legacyChanged = true ;
995
+ if (legacyStrings == null ) {
996
+ legacyStrings = new LinkedHashMap <>();
997
+ } else {
998
+ legacyStrings .replaceAll ((BiFunction <? super String , ? super String ,
999
+ ? extends String >) function );
1000
+ }
980
1001
super .replaceAll (function );
981
1002
}
982
1003
983
1004
@ SuppressWarnings ("unchecked" ) // Function must actually operate over strings
984
- private Object implMerge (Object key , Object value , BiFunction <? super Object ,
985
- ? super Object , ? extends Object > remappingFunction ) {
1005
+ private Object implMerge (Object key , Object value ,
1006
+ BiFunction <? super Object , ? super Object , ? extends Object >
1007
+ remappingFunction ) {
986
1008
if ((key instanceof String ) && (value instanceof String )) {
987
- if (isProviderInfo (key )) {
1009
+ if (! checkLegacy (key )) {
988
1010
return null ;
989
1011
}
990
- legacyChanged = true ;
1012
+ legacyStrings .merge ((String )key , (String )value ,
1013
+ (BiFunction <? super String , ? super String ,
1014
+ ? extends String >) remappingFunction );
991
1015
}
992
1016
return super .merge (key , value , remappingFunction );
993
1017
}
@@ -996,10 +1020,12 @@ private Object implMerge(Object key, Object value, BiFunction<? super Object,
996
1020
private Object implCompute (Object key , BiFunction <? super Object ,
997
1021
? super Object , ? extends Object > remappingFunction ) {
998
1022
if (key instanceof String ) {
999
- if (isProviderInfo (key )) {
1023
+ if (! checkLegacy (key )) {
1000
1024
return null ;
1001
1025
}
1002
- legacyChanged = true ;
1026
+ legacyStrings .compute ((String ) key ,
1027
+ (BiFunction <? super String ,? super String ,
1028
+ ? extends String >) remappingFunction );
1003
1029
}
1004
1030
return super .compute (key , remappingFunction );
1005
1031
}
@@ -1008,10 +1034,12 @@ private Object implCompute(Object key, BiFunction<? super Object,
1008
1034
private Object implComputeIfAbsent (Object key , Function <? super Object ,
1009
1035
? extends Object > mappingFunction ) {
1010
1036
if (key instanceof String ) {
1011
- if (isProviderInfo (key )) {
1037
+ if (! checkLegacy (key )) {
1012
1038
return null ;
1013
1039
}
1014
- legacyChanged = true ;
1040
+ legacyStrings .computeIfAbsent ((String ) key ,
1041
+ (Function <? super String , ? extends String >)
1042
+ mappingFunction );
1015
1043
}
1016
1044
return super .computeIfAbsent (key , mappingFunction );
1017
1045
}
@@ -1020,42 +1048,48 @@ private Object implComputeIfAbsent(Object key, Function<? super Object,
1020
1048
private Object implComputeIfPresent (Object key , BiFunction <? super Object ,
1021
1049
? super Object , ? extends Object > remappingFunction ) {
1022
1050
if (key instanceof String ) {
1023
- if (isProviderInfo (key )) {
1051
+ if (! checkLegacy (key )) {
1024
1052
return null ;
1025
1053
}
1026
- legacyChanged = true ;
1054
+ legacyStrings .computeIfPresent ((String ) key ,
1055
+ (BiFunction <? super String , ? super String ,
1056
+ ? extends String >) remappingFunction );
1027
1057
}
1028
1058
return super .computeIfPresent (key , remappingFunction );
1029
1059
}
1030
1060
1031
1061
private Object implPut (Object key , Object value ) {
1032
1062
if ((key instanceof String ) && (value instanceof String )) {
1033
- if (isProviderInfo (key )) {
1063
+ if (! checkLegacy (key )) {
1034
1064
return null ;
1035
1065
}
1036
- legacyChanged = true ;
1066
+ legacyStrings . put (( String ) key , ( String ) value ) ;
1037
1067
}
1038
1068
return super .put (key , value );
1039
1069
}
1040
1070
1041
1071
private Object implPutIfAbsent (Object key , Object value ) {
1042
1072
if ((key instanceof String ) && (value instanceof String )) {
1043
- if (isProviderInfo (key )) {
1073
+ if (! checkLegacy (key )) {
1044
1074
return null ;
1045
1075
}
1046
- legacyChanged = true ;
1076
+ legacyStrings . putIfAbsent (( String ) key , ( String ) value ) ;
1047
1077
}
1048
1078
return super .putIfAbsent (key , value );
1049
1079
}
1050
1080
1051
1081
private void implClear () {
1082
+ if (legacyStrings != null ) {
1083
+ legacyStrings .clear ();
1084
+ }
1052
1085
if (legacyMap != null ) {
1053
1086
legacyMap .clear ();
1054
1087
}
1055
1088
serviceMap .clear ();
1056
1089
legacyChanged = false ;
1057
1090
servicesChanged = false ;
1058
1091
serviceSet = null ;
1092
+ prngServices = null ;
1059
1093
super .clear ();
1060
1094
putId ();
1061
1095
}
@@ -1095,7 +1129,7 @@ boolean matches(String type, String algorithm) {
1095
1129
* service objects.
1096
1130
*/
1097
1131
private void ensureLegacyParsed () {
1098
- if (legacyChanged == false ) {
1132
+ if (legacyChanged == false || ( legacyStrings == null ) ) {
1099
1133
return ;
1100
1134
}
1101
1135
serviceSet = null ;
@@ -1104,7 +1138,7 @@ private void ensureLegacyParsed() {
1104
1138
} else {
1105
1139
legacyMap .clear ();
1106
1140
}
1107
- for (Map .Entry <?,? > entry : super .entrySet ()) {
1141
+ for (Map .Entry <String , String > entry : legacyStrings .entrySet ()) {
1108
1142
parseLegacyPut (entry .getKey (), entry .getValue ());
1109
1143
}
1110
1144
removeInvalidServices (legacyMap );
@@ -1125,12 +1159,12 @@ private void removeInvalidServices(Map<ServiceKey,Service> map) {
1125
1159
}
1126
1160
}
1127
1161
1128
- private String [] getTypeAndAlgorithm (String key ) {
1162
+ private static String [] getTypeAndAlgorithm (String key ) {
1129
1163
int i = key .indexOf ('.' );
1130
1164
if (i < 1 ) {
1131
1165
if (debug != null ) {
1132
- debug .println ("Ignoring invalid entry in provider "
1133
- + name + ":" + key );
1166
+ debug .println ("Ignoring invalid entry in provider: "
1167
+ + key );
1134
1168
}
1135
1169
return null ;
1136
1170
}
@@ -1143,15 +1177,7 @@ private String[] getTypeAndAlgorithm(String key) {
1143
1177
private static final String ALIAS_PREFIX_LOWER = "alg.alias." ;
1144
1178
private static final int ALIAS_LENGTH = ALIAS_PREFIX .length ();
1145
1179
1146
- private void parseLegacyPut (Object k , Object v ) {
1147
- if (!(k instanceof String ) || !(v instanceof String )) {
1148
- return ;
1149
- }
1150
- String name = (String ) k ;
1151
- String value = (String ) v ;
1152
- if (isProviderInfo (name )) {
1153
- return ;
1154
- }
1180
+ private void parseLegacyPut (String name , String value ) {
1155
1181
if (name .toLowerCase (ENGLISH ).startsWith (ALIAS_PREFIX_LOWER )) {
1156
1182
// e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1");
1157
1183
// aliasKey ~ MessageDigest.SHA
@@ -1193,6 +1219,10 @@ private void parseLegacyPut(Object k, Object v) {
1193
1219
legacyMap .put (key , s );
1194
1220
}
1195
1221
s .className = className ;
1222
+
1223
+ if (type .equals ("SecureRandom" )) {
1224
+ updateSecureRandomEntries (true , s );
1225
+ }
1196
1226
} else { // attribute
1197
1227
// e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
1198
1228
String attributeValue = value ;
@@ -1352,9 +1382,46 @@ protected void putService(Service s) {
1352
1382
servicesChanged = true ;
1353
1383
synchronized (this ) {
1354
1384
putPropertyStrings (s );
1385
+ if (type .equals ("SecureRandom" )) {
1386
+ updateSecureRandomEntries (true , s );
1387
+ }
1355
1388
}
1356
1389
}
1357
1390
1391
+ private void updateSecureRandomEntries (boolean doAdd , Service s ) {
1392
+ Objects .requireNonNull (s );
1393
+ if (doAdd ) {
1394
+ if (prngServices == null ) {
1395
+ prngServices = new LinkedHashSet <Service >();
1396
+ }
1397
+ prngServices .add (s );
1398
+ } else {
1399
+ prngServices .remove (s );
1400
+ }
1401
+
1402
+ if (debug != null ) {
1403
+ debug .println ((doAdd ? "Add" :"Remove" ) + " SecureRandom algo " +
1404
+ s .getAlgorithm ());
1405
+ }
1406
+ }
1407
+
1408
+ // used by new SecureRandom() to find out the default SecureRandom
1409
+ // service for this provider
1410
+ synchronized Service getDefaultSecureRandomService () {
1411
+ checkInitialized ();
1412
+
1413
+ if (legacyChanged ) {
1414
+ prngServices = null ;
1415
+ ensureLegacyParsed ();
1416
+ }
1417
+
1418
+ if (prngServices != null && !prngServices .isEmpty ()) {
1419
+ return prngServices .iterator ().next ();
1420
+ }
1421
+
1422
+ return null ;
1423
+ }
1424
+
1358
1425
/**
1359
1426
* Put the string properties for this Service in this Provider's
1360
1427
* Hashtable.
@@ -1448,6 +1515,9 @@ private void implRemoveService(Service s) {
1448
1515
}
1449
1516
synchronized (this ) {
1450
1517
removePropertyStrings (s );
1518
+ if (type .equals ("SecureRandom" )) {
1519
+ updateSecureRandomEntries (false , s );
1520
+ }
1451
1521
}
1452
1522
}
1453
1523
0 commit comments