昨天遇到读取配置文件的密码时,出现了转义字符 \ 导致认证失败。发现是密码包含转义字符导致的;
整理了一下Properties 的规则
key:从第一非空字符开始,如果key前面为空格、\t 都会被跳过;
到空格、\t、\f、冒号、等号为止;如果是转义符号加空格、冒号等 则会被读取;
举个栗子: bank\ code = 001 key为bank code
bank code = 001 ket为bank
value:从key后 空格、\t、\f、冒号、等号后开始,
如果key后是空格、\t、\f,且后面还跟着一个冒号或空格的,从冒号或空格后开始
1 private void load0 (LineReader lr) throws IOException { 2 char[] convtBuf = new char[1024]; 3 // 行数 4 int limit; 5 // key长度 6 int keyLen; 7 // value偏移量,即string截取起点 8 int valueStart; 9 // 当前处理的字符 10 char c; 11 // 是否为标准分隔符(等号或冒号) 12 boolean hasSep; 13 // 前面是否存在奇数个转义符号 14 boolean precedingBackslash; 15 16 while ((limit = lr.readLine()) >= 0) { 17 c = 0; 18 keyLen = 0; 19 valueStart = limit; 20 hasSep = false; 21 22 //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">"); 23 precedingBackslash = false; 24 // 循环遍历readLine读取的char 25 while (keyLen < limit) { 26 c = lr.lineBuf[keyLen]; 27 //need check if escaped. 28 // 如果是非转义的等号、冒号,key长度读取完成,hasSep为true 29 if ((c == '=' || c == ':') && !precedingBackslash) { 30 valueStart = keyLen + 1; 31 hasSep = true; 32 break; 33 // 如果是非转义的空格、\t、\f,key长度读取完成,hasSep为false 34 } else if ((c == ' ' || c == '\t' || c == '\f') && !precedingBackslash) { 35 valueStart = keyLen + 1; 36 break; 37 } 38 // 如果是转义符号,precedingBackslash取相反值,即奇数个转义字符时为true,偶数个为false 39 if (c == '\\') { 40 precedingBackslash = !precedingBackslash; 41 } else { 42 precedingBackslash = false; 43 } 44 keyLen++; 45 } 46 47 // 从key结束开始循环遍历char到结尾 48 while (valueStart < limit) { 49 c = lr.lineBuf[valueStart]; 50 // 如果不是空格、\t、\f则继续遍历 51 if (c != ' ' && c != '\t' && c != '\f') { 52 // 前一个字符不是等号、冒号,则从当前字符开始为value 53 // 前一个字符和当前字符是等号或冒号的,从下一个字符开始为value 54 if (!hasSep && (c == '=' || c == ':')) { 55 hasSep = true; 56 } else { 57 break; 58 } 59 } 60 valueStart++; 61 } 62 // 根据key的长度和value的偏移量开始截取key、value 63 String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf); 64 String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf); 65 put(key, value); 66 } 67 }