Launch a process with a parameter has double quotes

最近因為FW team把登入密碼限制給拿掉了,使得我們需要去面對密碼中有特殊字元的問題,其中最難搞的問題就是double-quotes。當你需要執行外部程式時,如果參數有特殊字元你要怎麼處理?

這問題是會與OS有關的。如果是下command line,在linux上的雙引號可以這樣處理:

'xxx"xxx'
"xxx\"xxx"
xxx\"xxx
而windows上,則要在雙引號前多加雙引號:
xxx""xxx
經過測試,透過ProcessBuilder時,需要特別處理的只有Windows:
	private static List<String> processDoubleQouteChar(List<String> aParams){
		if(!PlatformUtil.isWindows()){
			return aParams;
		}
 
		List<String> param = new ArrayList<>();
		for( String token : aParams ){
			if(token.contains("\"")){
				token = StringUtil.apendStrings("\"", token.replace("\"", "\"\""), "\"");
			}
			param.add(token);
		}
		return param;
	}
 
	private static ProcessBuilder createProcessBuilder(List<String> aParams){
		return new ProcessBuilder(processDoubleQouteChar(aParams));
	}
首先是如果字串內有雙引號,就需要透過雙引號去跳脫;但如果雙引號是在前後,會導致PrcoessBuilder不會再額外+雙引號上去,所以client要先+上去。

除了ProcessBuilder,我們還遇到commons-cli parse參數中,如果包含double-quotes會被消掉的問題。在1.2版本上,如果你的參數為:

"test"
經過Parse後,前後double-quotes就會被去掉;這是由於Parser實作針對Value會去呼叫Util.stripLeadingAndTrailingQuotes,而裡面會去掉開頭與結尾的雙引號。在1.3版本上,是有額外判斷內容是否包含雙引號才決定是否去頭去尾。面對這問題,最後是透過override Parser的以下method,去掉stripLeadingAndTrailingQuotes動作避免問題。
public void processArgs(Option opt, ListIterator iter) throws ParseException