20
20
import redis .clients .jedis .exceptions .JedisConnectionException ;
21
21
import redis .clients .jedis .exceptions .JedisDataException ;
22
22
import redis .clients .jedis .exceptions .JedisException ;
23
+ import redis .clients .jedis .exceptions .JedisValidationException ;
23
24
import redis .clients .jedis .util .IOUtils ;
24
25
import redis .clients .jedis .util .JedisMetaInfo ;
25
26
import redis .clients .jedis .util .RedisInputStream ;
@@ -370,6 +371,23 @@ public List<Object> getMany(final int count) {
370
371
return responses ;
371
372
}
372
373
374
+ /**
375
+ * Check if the client name libname, libver, characters are legal
376
+ * @param info the name
377
+ * @return Returns true if legal, false throws exception
378
+ * @throws JedisException if characters illegal
379
+ */
380
+ private static boolean validateClientInfo (String info ) {
381
+ for (int i = 0 ; i < info .length (); i ++) {
382
+ char c = info .charAt (i );
383
+ if (c < '!' || c > '~' ) {
384
+ throw new JedisValidationException ("client info cannot contain spaces, "
385
+ + "newlines or special characters." );
386
+ }
387
+ }
388
+ return true ;
389
+ }
390
+
373
391
private void initializeFromClientConfig (JedisClientConfig config ) {
374
392
try {
375
393
connect ();
@@ -387,9 +405,12 @@ private void initializeFromClientConfig(JedisClientConfig config) {
387
405
388
406
Supplier <RedisCredentials > credentialsProvider = config .getCredentialsProvider ();
389
407
if (credentialsProvider instanceof RedisCredentialsProvider ) {
390
- ((RedisCredentialsProvider ) credentialsProvider ).prepare ();
391
- auth (credentialsProvider );
392
- ((RedisCredentialsProvider ) credentialsProvider ).cleanUp ();
408
+ try {
409
+ ((RedisCredentialsProvider ) credentialsProvider ).prepare ();
410
+ auth (credentialsProvider );
411
+ } finally {
412
+ ((RedisCredentialsProvider ) credentialsProvider ).cleanUp ();
413
+ }
393
414
} else {
394
415
auth (credentialsProvider );
395
416
}
@@ -398,59 +419,37 @@ private void initializeFromClientConfig(JedisClientConfig config) {
398
419
hello (protocol );
399
420
}
400
421
}
401
- /// HELLO and AUTH
402
-
403
- List <CommandArguments > fireAndForgetMsg = new ArrayList <>();
404
422
405
423
int dbIndex = config .getDatabase ();
406
424
if (dbIndex > 0 ) {
407
- fireAndForgetMsg . add ( new CommandArguments ( Command . SELECT ). add ( Protocol . toByteArray ( dbIndex )) );
425
+ select ( dbIndex );
408
426
}
409
427
428
+ List <CommandArguments > fireAndForgetMsg = new ArrayList <>();
429
+
410
430
String clientName = config .getClientName ();
411
- if (doClientName && clientName != null ) {
431
+ if (doClientName && clientName != null && validateClientInfo ( clientName ) ) {
412
432
fireAndForgetMsg .add (new CommandArguments (Command .CLIENT ).add (Keyword .SETNAME ).add (clientName ));
413
433
}
414
434
415
435
String libName = JedisMetaInfo .getArtifactId ();
416
- if (libName != null ) {
436
+ if (libName != null && validateClientInfo ( libName ) ) {
417
437
fireAndForgetMsg .add (new CommandArguments (Command .CLIENT ).add (Keyword .SETINFO )
418
438
.add (ClientAttributeOption .LIB_NAME .getRaw ()).add (libName ));
419
439
}
420
440
421
441
String libVersion = JedisMetaInfo .getVersion ();
422
- if (libVersion != null ) {
442
+ if (libVersion != null && validateClientInfo ( libVersion ) ) {
423
443
fireAndForgetMsg .add (new CommandArguments (Command .CLIENT ).add (Keyword .SETINFO )
424
444
.add (ClientAttributeOption .LIB_VER .getRaw ()).add (libVersion ));
425
445
}
426
446
427
447
for (CommandArguments arg : fireAndForgetMsg ) {
428
448
sendCommand (arg );
429
449
}
430
-
431
- List <Object > objects = getMany (fireAndForgetMsg .size ());
432
- for (Object obj : objects ) {
433
- if (obj instanceof JedisDataException ) {
434
- JedisDataException e = (JedisDataException )obj ;
435
- String errorMsg = e .getMessage ().toUpperCase ();
436
- /**
437
- * 1. Redis 4.0 and before, we need to ignore `Syntax error`.
438
- * 2. Redis 5.0 and later, we need to ignore `Unknown subcommand error`.
439
- * 3. Because Jedis allows Jedis jedis = new Jedis() in advance, and jedis.auth(password) later,
440
- * we need to ignore `NOAUTH errors`.
441
- */
442
- if (errorMsg .contains ("SYNTAX" ) ||
443
- errorMsg .contains ("UNKNOWN" ) ||
444
- errorMsg .contains ("NOAUTH" )) { // TODO: not filter out NOAUTH
445
- // ignore
446
- } else {
447
- throw e ;
448
- }
449
- }
450
- }
450
+ getMany (fireAndForgetMsg .size ());
451
451
} catch (JedisException je ) {
452
452
try {
453
- setBroken ();
454
453
disconnect ();
455
454
} catch (Exception e ) {
456
455
// the first exception 'je' will be thrown
@@ -504,6 +503,11 @@ private void auth(final Supplier<RedisCredentials> credentialsProvider) {
504
503
getStatusCodeReply (); // OK
505
504
}
506
505
506
+ public String select (final int index ) {
507
+ sendCommand (Protocol .Command .SELECT , Protocol .toByteArray (index ));
508
+ return getStatusCodeReply ();
509
+ }
510
+
507
511
public boolean ping () {
508
512
sendCommand (Protocol .Command .PING );
509
513
String status = getStatusCodeReply ();
0 commit comments