| 
41 | 41 | import static com.launchdarkly.sdk.EvaluationDetail.NO_VARIATION;  | 
42 | 42 | import static com.launchdarkly.sdk.server.DataModel.FEATURES;  | 
43 | 43 | import static com.launchdarkly.sdk.server.DataModel.SEGMENTS;  | 
 | 44 | +import static com.launchdarkly.sdk.server.Util.isAsciiHeaderValue;  | 
44 | 45 | 
 
  | 
45 | 46 | /**  | 
46 | 47 |  * A client for the LaunchDarkly API. Client instances are thread-safe. Applications should instantiate  | 
@@ -82,8 +83,15 @@ public final class LDClient implements LDClientInterface {  | 
82 | 83 |  * values; it will still continue trying to connect in the background. You can detect whether  | 
83 | 84 |  * initialization has succeeded by calling {@link #isInitialized()}. If you prefer to customize  | 
84 | 85 |  * this behavior, use {@link LDClient#LDClient(String, LDConfig)} instead.  | 
 | 86 | + * <p>  | 
 | 87 | + * For rules regarding the throwing of unchecked exceptions for error conditions, see  | 
 | 88 | + * {@link LDClient#LDClient(String, LDConfig)}.  | 
85 | 89 |  *  | 
86 | 90 |  * @param sdkKey the SDK key for your LaunchDarkly environment  | 
 | 91 | + * @throws IllegalArgumentException if a parameter contained a grossly malformed value;  | 
 | 92 | + * for security reasons, in case of an illegal SDK key, the exception message does  | 
 | 93 | + * not include the key  | 
 | 94 | + * @throws NullPointerException if a non-nullable parameter was null  | 
87 | 95 |  * @see LDClient#LDClient(String, LDConfig)  | 
88 | 96 |  */  | 
89 | 97 |  public LDClient(String sdkKey) {  | 
@@ -136,14 +144,32 @@ private static final DataModel.Segment getSegment(DataStore store, String key) {  | 
136 | 144 |  * // do whatever is appropriate if initialization has timed out  | 
137 | 145 |  * }  | 
138 | 146 |  * </code></pre>  | 
 | 147 | + * <p>  | 
 | 148 | + * This constructor can throw unchecked exceptions if it is immediately apparent that  | 
 | 149 | + * the SDK cannot work with these parameters. For instance, if the SDK key contains a  | 
 | 150 | + * non-printable character that cannot be used in an HTTP header, it will throw an  | 
 | 151 | + * {@link IllegalArgumentException} since the SDK key is normally sent to LaunchDarkly  | 
 | 152 | + * in an HTTP header and no such value could possibly be valid. Similarly, a null  | 
 | 153 | + * value for a non-nullable parameter may throw a {@link NullPointerException}. The  | 
 | 154 | + * constructor will not throw an exception for any error condition that could only be  | 
 | 155 | + * detected after making a request to LaunchDarkly (such as an SDK key that is simply  | 
 | 156 | + * wrong despite being valid ASCII, so it is invalid but not illegal); those are logged  | 
 | 157 | + * and treated as an unsuccessful initialization, as described above.   | 
139 | 158 |  *  | 
140 | 159 |  * @param sdkKey the SDK key for your LaunchDarkly environment  | 
141 | 160 |  * @param config a client configuration object  | 
 | 161 | + * @throws IllegalArgumentException if a parameter contained a grossly malformed value;  | 
 | 162 | + * for security reasons, in case of an illegal SDK key, the exception message does  | 
 | 163 | + * not include the key  | 
 | 164 | + * @throws NullPointerException if a non-nullable parameter was null  | 
142 | 165 |  * @see LDClient#LDClient(String, LDConfig)  | 
143 | 166 |  */  | 
144 | 167 |  public LDClient(String sdkKey, LDConfig config) {  | 
145 | 168 |  checkNotNull(config, "config must not be null");  | 
146 | 169 |  this.sdkKey = checkNotNull(sdkKey, "sdkKey must not be null");  | 
 | 170 | + if (!isAsciiHeaderValue(sdkKey) ) {  | 
 | 171 | + throw new IllegalArgumentException("SDK key contained an invalid character");  | 
 | 172 | + }  | 
147 | 173 |  this.offline = config.offline;  | 
148 | 174 | 
 
  | 
149 | 175 |  this.sharedExecutor = createSharedExecutor(config);  | 
 | 
0 commit comments