List of usage examples for java.util.regex Matcher quoteReplacement
public static String quoteReplacement(String s)
From source file:com.cisco.dvbu.ps.common.util.CommonUtils.java
/** * Decode CIS paths by replacing encoded values with real values. * Modify CommonConstants.pathCodes to modify the array of encoded values and real values. * /*from w ww .j a v a2 s.c o m*/ * @param path * @return */ public static String decodePath(String path) { for (int i = 0; i < CommonConstants.pathCodes.length; i++) { String symbol = CommonConstants.pathCodes[i][0]; String encodedValue = CommonConstants.pathCodes[i][1]; // Decode encodedValue to a symbol if (path.contains(encodedValue)) path = path.replaceAll(Matcher.quoteReplacement(encodedValue), Matcher.quoteReplacement(symbol)); } return path; }
From source file:org.wso2.connector.integration.test.base.ConnectorIntegrationTestBase.java
/** * This method de-serialize XML object graph. In addition if there are parameterized strings such as * <code>%s(accessToken)</code> in the XML file, those will be parsed and and replace with the values * specified in the Connection Properties resource file or the parameter map passed in to this method. <br> * <br>/*from w ww .ja va 2s. c om*/ * <b>Example XML file.</b><br> * * <pre> * {@code * <?xml version="1.0" encoding="UTF-8"?> * <java class="java.beans.XMLDecoder"> * <object class="test.base.Person"> * <void property="address"> * <object class="test.base.Address"> * <void property="city"> * <string>Test City</string> * </void> * <void property="country"> * <string>Test Country</string> * </void> * <void property="street"> * <string>Test street</string> * </void> * </object> * </void> * <void property="age"> * <int>20</int> * </void> * <void property="name"> * <string>Test Person Name</string> * </void> * </object> * </java> * } * </pre> * * @param filePath file name including path to the XML serialized file. * @param paramMap map containing key value pairs where key being the parameter specified in the XML file * if parameter in XML is <code>%s(accessToken)</code>, the key should be just * <code>accessToken</code>. * @return the de-serialized object, user can cast this to the object type specified in the XML. * @throws IOException if file path is null or empty as well as if there's any exception while reading the * XML file. */ protected Object loadObjectFromFile(String fileName, Map<String, String> paramMap) throws IOException { String filePath = pathToRequestsDirectory + fileName; if (filePath == null || filePath.isEmpty()) { throw new IOException("File path cannot be null or empty."); } Object retObj = null; BufferedInputStream bi = null; XMLDecoder decoder = null; try { bi = new BufferedInputStream(new FileInputStream(filePath)); byte[] buf = new byte[bi.available()]; bi.read(buf); String content = new String(buf); if (connectorProperties != null) { // We don't need to change the original connection properties in case same key is sent with // different value. Properties prop = (Properties) connectorProperties.clone(); if (paramMap != null) { prop.putAll(paramMap); } Matcher matcher = Pattern.compile("%s\\(([A-Za-z0-9]*)\\)", Pattern.DOTALL).matcher(content); while (matcher.find()) { String key = matcher.group(1); content = content.replaceAll("%s\\(" + key + "\\)", Matcher.quoteReplacement(prop.getProperty(key))); } } ByteArrayInputStream in = new ByteArrayInputStream(content.getBytes(Charset.defaultCharset())); decoder = new XMLDecoder(in); retObj = decoder.readObject(); } finally { if (bi != null) { bi.close(); } if (decoder != null) { decoder.close(); } } return retObj; }
From source file:edu.harvard.iq.dataverse.ingest.tabulardata.impl.plugins.por.PORFileReader.java
private void decodeData(BufferedReader reader) throws IOException { dbgLog.fine("decodeData(): start"); // TODO: get rid of this "variableTypeFinal"; -- L.A. 4.0 beta int[] variableTypeFinal = new int[varQnty]; dateFormatList = new String[varQnty]; // create a File object to save the tab-delimited data file File tabDelimitedDataFile = File.createTempFile("tempTabfile.", ".tab"); ingesteddata.setTabDelimitedFile(tabDelimitedDataFile); FileOutputStream fileOutTab = null; PrintWriter pwout = null;/*from ww w . ja v a2 s . com*/ try { fileOutTab = new FileOutputStream(tabDelimitedDataFile); pwout = new PrintWriter(new OutputStreamWriter(fileOutTab, "utf8"), true); variableFormatTypeList = new String[varQnty]; for (int i = 0; i < varQnty; i++) { variableFormatTypeList[i] = SPSSConstants.FORMAT_CATEGORY_TABLE .get(printFormatTable.get(variableNameList.get(i))); formatCategoryTable.put(variableNameList.get(i), variableFormatTypeList[i]); } // contents (variable) checker concering decimals Arrays.fill(variableTypeFinal, 0); // raw-case counter int j = 0; // case // use while instead for because the number of cases (observations) is usually unknown FBLOCK: while (true) { j++; // case(row)-wise storage object; to be updated after each row-reading String[] casewiseRecordForTabFile = new String[varQnty]; // warning: the above object is later shallow-copied to the // data object for calculating a UNF value/summary statistics // for (int i = 0; i < varQnty; i++) { // check the type of this variable boolean isStringType = variableTypeTable.get(variableNameList.get(i)) > 0; if (isStringType) { // String case variableTypeFinal[i] = -1; StringBuilder sb_StringLengthBase30 = new StringBuilder(""); int stringLengthBase10 = 0; String buffer = ""; char[] tmp = new char[1]; int nint; while ((nint = reader.read(tmp)) > 0) { buffer = Character.toString(tmp[0]); if (buffer.equals("/")) { break; } else if (buffer.equals("Z")) { if (i == 0) { // the reader has passed the last case; subtract 1 from the j counter caseQnty = j - 1; break FBLOCK; } } else { sb_StringLengthBase30.append(buffer); } } if (nint == 0) { // no more data to be read (reached the eof) caseQnty = j - 1; break FBLOCK; } dbgLog.finer( j + "-th case " + i + "=th var:datum length=" + sb_StringLengthBase30.toString()); // this length value should be a positive integer Matcher mtr = pattern4positiveInteger.matcher(sb_StringLengthBase30.toString()); if (mtr.matches()) { stringLengthBase10 = Integer.valueOf(sb_StringLengthBase30.toString(), 30); } else { // reading error case throw new IOException("reading F(data) section: string: length is not integer"); } // read this string-variable's contents after "/" char[] char_datumString = new char[stringLengthBase10]; reader.read(char_datumString); String datum = new String(char_datumString); casewiseRecordForTabFile[i] = "\"" + datum.replaceAll("\"", Matcher.quoteReplacement("\\\"")) + "\""; // end of string case } else { // numeric case StringBuilder sb_datumNumericBase30 = new StringBuilder(""); boolean isMissingValue = false; String datum = null; String datumForTabFile = null; String datumDateFormat = null; String buffer = ""; char[] tmp = new char[1]; int nint; while ((nint = reader.read(tmp)) > 0) { sb_datumNumericBase30.append(buffer); buffer = Character.toString(tmp[0]); if (buffer.equals("/")) { break; } else if (buffer.equals("Z")) { if (i == 0) { // the reader has passed the last case // subtract 1 from the j counter dbgLog.fine("Z-mark was detected"); caseQnty = j - 1; break FBLOCK; } } else if (buffer.equals("*")) { // '*' is the first character of the system missing value datumForTabFile = MissingValueForTextDataFile; datum = null; isMissingValue = true; // read next char '.' as part of the missing value reader.read(tmp); buffer = Character.toString(tmp[0]); break; } } if (nint == 0) { // no more data to be read; reached the eof caseQnty = j - 1; break FBLOCK; } // follow-up process for non-missing-values if (!isMissingValue) { // decode a numeric datum as String String datumNumericBase30 = sb_datumNumericBase30.toString(); Matcher matcher = pattern4Integer.matcher(datumNumericBase30); if (matcher.matches()) { // integer case datum = Long.valueOf(datumNumericBase30, 30).toString(); } else { // double case datum = doubleNumberFormatter.format(base30Tobase10Conversion(datumNumericBase30)); } // now check format (if date or time) String variableFormatType = variableFormatTypeList[i]; if (variableFormatType.equals("date")) { variableTypeFinal[i] = -1; long dateDatum = Long.parseLong(datum) * 1000L - SPSS_DATE_OFFSET; datum = sdf_ymd.format(new Date(dateDatum)); datumDateFormat = sdf_ymd.toPattern(); } else if (variableFormatType.equals("time")) { variableTypeFinal[i] = -1; int formatDecimalPointPosition = formatDecimalPointPositionList.get(i); if (printFormatTable.get(variableNameList.get(i)).equals("DTIME")) { if (datum.indexOf(".") < 0) { long dateDatum = Long.parseLong(datum) * 1000L - SPSS_DATE_BIAS; datum = sdf_dhms.format(new Date(dateDatum)); // don't save date format for dtime } else { // decimal point included String[] timeData = datum.split("\\."); long dateDatum = Long.parseLong(timeData[0]) * 1000L - SPSS_DATE_BIAS; StringBuilder sb_time = new StringBuilder( sdf_dhms.format(new Date(dateDatum))); if (formatDecimalPointPosition > 0) { sb_time.append( "." + timeData[1].substring(0, formatDecimalPointPosition)); } datum = sb_time.toString(); // DTIME is weird date/time format that no one uses outside of // SPSS; so we are not even going to bother trying to save // this variable as a datetime. } } else if (printFormatTable.get(variableNameList.get(i)).equals("DATETIME")) { // TODO: // (for both datetime and "dateless" time) // keep the longest of the matching formats - i.e., if there are *some* // values in the vector that have thousands of a second, that should be // part of the saved format! // -- L.A. Aug. 12 2014 if (!datum.contains(".")) { long dateDatum = Long.parseLong(datum) * 1000L - SPSS_DATE_OFFSET; datum = sdf_ymdhms.format(new Date(dateDatum)); datumDateFormat = sdf_ymdhms.toPattern(); } else { // decimal point included String[] timeData = datum.split("\\."); long dateDatum = Long.parseLong(timeData[0]) * 1000L - SPSS_DATE_OFFSET; StringBuilder sb_time = new StringBuilder( sdf_ymdhms.format(new Date(dateDatum))); if (formatDecimalPointPosition > 0) { sb_time.append( "." + timeData[1].substring(0, formatDecimalPointPosition)); } datum = sb_time.toString(); datumDateFormat = sdf_ymdhms.toPattern() + (formatDecimalPointPosition > 0 ? ".S" : ""); } } else if (printFormatTable.get(variableNameList.get(i)).equals("TIME")) { if (!datum.contains(".")) { long dateDatum = Long.parseLong(datum) * 1000L; datum = sdf_hms.format(new Date(dateDatum)); datumDateFormat = sdf_hms.toPattern(); } else { // decimal point included String[] timeData = datum.split("\\."); long dateDatum = Long.parseLong(timeData[0]) * 1000L; StringBuilder sb_time = new StringBuilder( sdf_hms.format(new Date(dateDatum))); if (formatDecimalPointPosition > 0) { sb_time.append( "." + timeData[1].substring(0, formatDecimalPointPosition)); } datum = sb_time.toString(); datumDateFormat = sdf_hms.toPattern() + (formatDecimalPointPosition > 0 ? ".S" : ""); } } } else if (variableFormatType.equals("other")) { if (printFormatTable.get(variableNameList.get(i)).equals("WKDAY")) { // day of week variableTypeFinal[i] = -1; datum = SPSSConstants.WEEKDAY_LIST.get(Integer.valueOf(datum) - 1); } else if (printFormatTable.get(variableNameList.get(i)).equals("MONTH")) { // month variableTypeFinal[i] = -1; datum = SPSSConstants.MONTH_LIST.get(Integer.valueOf(datum) - 1); } } // since value is not missing, set both values to be the same datumForTabFile = datum; // decimal-point check (variable is integer or not) if (variableTypeFinal[i] == 0) { if (datum.contains(".")) { variableTypeFinal[i] = 1; decimalVariableSet.add(i); } } } if (datumDateFormat != null) { dateFormatList[i] = datumDateFormat; } casewiseRecordForTabFile[i] = datumForTabFile; } // end: if: string vs numeric variable } // end:for-loop-i (variable-wise loop) // print the i-th case; use casewiseRecord to dump the current case to the tab-delimited file pwout.println(StringUtils.join(casewiseRecordForTabFile, "\t")); } // end: while-block } finally { // close the print writer if (pwout != null) { pwout.close(); } } ///smd.setDecimalVariables(decimalVariableSet); dataTable.setCaseQuantity(new Long(caseQnty)); dbgLog.fine("decodeData(): end"); }
From source file:org.springframework.integration.dsl.test.IntegrationFlowTests.java
@Test @SuppressWarnings("unchecked") public void testFtpMgetFlow() { String dir = "ftpSource/"; this.ftpMgetInputChannel.send(new GenericMessage<Object>(dir + "*")); Message<?> result = this.remoteFileOutputChannel.receive(1000); assertNotNull(result);/*from www.j a va2 s .com*/ List<java.io.File> localFiles = (List<java.io.File>) result.getPayload(); // should have filtered ftpSource2.txt assertEquals(2, localFiles.size()); for (java.io.File file : localFiles) { assertThat(file.getPath().replaceAll(Matcher.quoteReplacement(java.io.File.separator), "/"), Matchers.containsString(dir)); } assertThat(localFiles.get(1).getPath().replaceAll(Matcher.quoteReplacement(java.io.File.separator), "/"), Matchers.containsString(dir + "subFtpSource")); }
From source file:org.springframework.integration.dsl.test.IntegrationFlowTests.java
@Test @SuppressWarnings("unchecked") public void testSftpMgetFlow() { String dir = "sftpSource/"; this.sftpMgetInputChannel.send(new GenericMessage<Object>(dir + "*")); Message<?> result = this.remoteFileOutputChannel.receive(1000); assertNotNull(result);//from ww w .j av a2s .co m List<java.io.File> localFiles = (List<java.io.File>) result.getPayload(); // should have filtered sftpSource2.txt assertEquals(2, localFiles.size()); for (java.io.File file : localFiles) { assertThat(file.getPath().replaceAll(Matcher.quoteReplacement(java.io.File.separator), "/"), Matchers.containsString(dir)); } assertThat(localFiles.get(1).getPath().replaceAll(Matcher.quoteReplacement(java.io.File.separator), "/"), Matchers.containsString(dir + "subSftpSource")); }
From source file:org.zaproxy.zap.extension.ascanrulesBeta.SessionFixation.java
/** * scans all GET, Cookie params for Session fields, and looks for SessionFixation * vulnerabilities//from w w w . j av a 2 s . c o m */ @Override public void scan() { // TODO: scan the POST (form) params for session id fields. try { boolean loginUrl = false; // Are we dealing with a login url in any of the contexts of which this uri is part URI requestUri = getBaseMsg().getRequestHeader().getURI(); ExtensionAuthentication extAuth = (ExtensionAuthentication) Control.getSingleton().getExtensionLoader() .getExtension(ExtensionAuthentication.NAME); // using the session, get the list of contexts for the url List<Context> contextList = extAuth.getModel().getSession().getContextsForUrl(requestUri.getURI()); // now loop, and see if the url is a login url in each of the contexts in turn... for (Context context : contextList) { URI loginUri = extAuth.getLoginRequestURIForContext(context); if (loginUri != null && requestUri.getPath() != null) { if (requestUri.getScheme().equals(loginUri.getScheme()) && requestUri.getHost().equals(loginUri.getHost()) && requestUri.getPort() == loginUri.getPort() && requestUri.getPath().equals(loginUri.getPath())) { // we got this far.. only the method (GET/POST), user details, query params, // fragment, and POST params // are possibly different from the login page. loginUrl = true; break; } } } // For now (from Zap 2.0), the Session Fixation scanner will only run for login pages if (loginUrl == false) { log.debug("For the Session Fixation scanner to actually do anything, a Login Page *must* be set!"); return; } // find all params set in the request (GET/POST/Cookie) // Note: this will be the full set, before we delete anything. TreeSet<HtmlParameter> htmlParams = new TreeSet<>(); htmlParams.addAll(getBaseMsg().getRequestHeader().getCookieParams()); // request cookies only. no response cookies htmlParams.addAll(getBaseMsg().getFormParams()); // add in the POST params htmlParams.addAll(getBaseMsg().getUrlParams()); // add in the GET params // Now add in the pseudo parameters set in the URL itself, such as in the following: // http://www.example.com/someurl;JSESSIONID=abcdefg?x=123&y=456 // as opposed to the url parameters in the following example, which are already picked // up by getUrlParams() // http://www.example.com/someurl?JSESSIONID=abcdefg&x=123&y=456 // convert from org.apache.commons.httpclient.URI to a String String requestUrl = "Unknown URL"; try { requestUrl = new URL(requestUri.getScheme(), requestUri.getHost(), requestUri.getPort(), requestUri.getPath()).toString(); } catch (Exception e) { // no point in continuing. The URL is invalid. This is a peculiarity in the Zap // core, // and can happen when // - the user browsed to http://www.example.com/bodgeit and // - the user did not browse to http://www.example.com or to http://www.example.com/ // so the Zap GUI displays "http://www.example.com" as a node under "Sites", // and under that, it displays the actual urls to which the user browsed // (http://www.example.com/bodgeit, for instance) // When the user selects the node "http://www.example.com", and tries to scan it // with // the session fixation scanner, the URI that is passed is "http://www.example.com", // which is *not* a valid url. // If the user actually browses to "http://www.example.com" (even without the // trailing slash) // the web browser appends the trailing slash, and so Zap records the URI as // "http://www.example.com/", which IS a valid url, and which can (and should) be // scanned. // // In short.. if this happens, we do not want to scan the URL anyway // (because the user never browsed to it), so just do nothing instead. log.error("Cannot convert URI [" + requestUri + "] to a URL: " + e.getMessage()); return; } // suck out any pseudo url parameters from the url Set<HtmlParameter> pseudoUrlParams = getPseudoUrlParameters(requestUrl); htmlParams.addAll(pseudoUrlParams); if (this.debugEnabled) log.debug("Pseudo url params of URL [" + requestUrl + "] : [" + pseudoUrlParams + "]"); //// for each parameter in turn, // int counter = 0; for (Iterator<HtmlParameter> iter = htmlParams.iterator(); iter.hasNext();) { HttpMessage msg1Final; HttpMessage msg1Initial = getNewMsg(); //// debug logic only.. to do first field only // counter ++; // if ( counter > 1 ) // return; HtmlParameter currentHtmlParameter = iter.next(); // Useful for debugging, but I can't find a way to view this data in the GUI, so // leave it out for now. // msg1Initial.setNote("Message 1 for parameter "+ currentHtmlParameter); if (this.debugEnabled) log.debug("Scanning URL [" + msg1Initial.getRequestHeader().getMethod() + "] [" + msg1Initial.getRequestHeader().getURI() + "], [" + currentHtmlParameter.getType() + "] field [" + currentHtmlParameter.getName() + "] with value [" + currentHtmlParameter.getValue() + "] for Session Fixation"); if (currentHtmlParameter.getType().equals(HtmlParameter.Type.cookie)) { // careful to pick up the cookies from the Request, and not to include cookies // set in any earlier response TreeSet<HtmlParameter> cookieRequestParams = msg1Initial.getRequestHeader().getCookieParams(); // delete the original cookie from the parameters cookieRequestParams.remove(currentHtmlParameter); msg1Initial.setCookieParams(cookieRequestParams); // send the message, minus the cookie parameter, and see how it comes back. // Note: do NOT automatically follow redirects.. handle those here instead. sendAndReceive(msg1Initial, false, false); ///////////////////////////// // create a copy of msg1Initial to play with to handle redirects (if any). // we use a copy because if we change msg1Initial itself, it messes the URL and // params displayed on the GUI. msg1Final = msg1Initial; HtmlParameter cookieBack1 = getResponseCookie(msg1Initial, currentHtmlParameter.getName()); long cookieBack1TimeReceived = System.currentTimeMillis(); // in ms. when was the cookie received? // Important if it has a Max-Age directive Date cookieBack1ExpiryDate = null; HttpMessage temp = msg1Initial; int redirectsFollowed1 = 0; while (HttpStatusCode.isRedirection(temp.getResponseHeader().getStatusCode())) { // Note that we need to clone the Request and the Response.. // we seem to need to track the secure flag now to make sure its set later boolean secure1 = temp.getRequestHeader().isSecure(); temp = temp.cloneAll(); // clone the previous message redirectsFollowed1++; if (redirectsFollowed1 > 10) { throw new Exception("Too many redirects were specified in the first message"); } // create a new URI from the absolute location returned, and interpret it as // escaped // note that the standard says that the Location returned should be // absolute, but it ain't always so... URI newLocation = new URI(temp.getResponseHeader().getHeader(HttpHeader.LOCATION), true); // and follow the forward url // need to clear the params (which would come from the initial POST, // otherwise) temp.getRequestHeader().setGetParams(new TreeSet<HtmlParameter>()); temp.setRequestBody(""); temp.setResponseBody(""); // make sure no values accidentally carry from one iteration to // the next try { temp.getRequestHeader().setURI(newLocation); } catch (Exception e) { // the Location field contents may not be standards compliant. Lets // generate a uri to use as a workaround where a relative path was // given instead of an absolute one URI newLocationWorkaround = new URI(temp.getRequestHeader().getURI(), temp.getResponseHeader().getHeader(HttpHeader.LOCATION), true); // try again, except this time, if it fails, don't try to handle it if (this.debugEnabled) log.debug("The Location [" + newLocation + "] specified in a redirect was not valid. Trying workaround url [" + newLocationWorkaround + "]"); temp.getRequestHeader().setURI(newLocationWorkaround); } temp.getRequestHeader().setSecure(secure1); temp.getRequestHeader().setMethod(HttpRequestHeader.GET); temp.getRequestHeader().setContentLength(0); // since we send a GET, the body will be 0 long if (cookieBack1 != null) { // if the previous request sent back a cookie, we need to set that // cookie when following redirects, as a browser would if (this.debugEnabled) log.debug("Adding in cookie [" + cookieBack1 + "] for a redirect"); TreeSet<HtmlParameter> forwardCookieParams = temp.getRequestHeader().getCookieParams(); forwardCookieParams.add(cookieBack1); temp.getRequestHeader().setCookieParams(forwardCookieParams); } if (this.debugEnabled) log.debug("DEBUG: Cookie Message 1 causes us to follow redirect to [" + newLocation + "]"); sendAndReceive(temp, false, false); // do NOT redirect.. handle it here // handle any cookies set from following redirects that override the cookie // set in the redirect itself (if any) // note that this will handle the case where a latter cookie unsets one set // earlier. HtmlParameter cookieBack1Temp = getResponseCookie(temp, currentHtmlParameter.getName()); if (cookieBack1Temp != null) { cookieBack1 = cookieBack1Temp; cookieBack1TimeReceived = System.currentTimeMillis(); // in ms. record when we got the // cookie.. in case it has a // Max-Age directive } // reset the "final" version of message1 to use the final response in the // chain msg1Final = temp; } /////////////////////////// // if non-200 on the final response for message 1, no point in continuing. Bale // out. if (msg1Final.getResponseHeader().getStatusCode() != HttpStatusCode.OK) { if (this.debugEnabled) log.debug( "Got a non-200 response code [" + msg1Final.getResponseHeader().getStatusCode() + "] when sending [" + msg1Initial.getRequestHeader().getURI() + "] with param [" + currentHtmlParameter.getName() + "] = NULL (possibly somewhere in the redirects)"); continue; } // now check that the response set a cookie. if it didn't, then either.. // 1) we are messing with the wrong field // 2) the app doesn't do sessions // either way, there is not much point in continuing to look at this field.. if (cookieBack1 == null || cookieBack1.getValue() == null) { // no cookie was set, or the cookie param was set to a null value if (this.debugEnabled) log.debug("The Cookie parameter was NOT set in the response, when cookie param [" + currentHtmlParameter.getName() + "] was set to NULL: " + cookieBack1); continue; } ////////////////////////////////////////////////////////////////////// // at this point, before continuing to check for Session Fixation, do some other // checks on the session cookie we got back // that might cause us to raise additional alerts (in addition to doing the main // check for Session Fixation) ////////////////////////////////////////////////////////////////////// // Check 1: was the session cookie sent and received securely by the server? // If not, alert this fact if ((!msg1Final.getRequestHeader().isSecure()) || (!cookieBack1.getFlags().contains("secure"))) { // pass the original param value here, not the new value, since we're // displaying the session id exposed in the original message String extraInfo = Constant.messages.getString( "ascanbeta.sessionidsentinsecurely.alert.extrainfo", currentHtmlParameter.getType(), currentHtmlParameter.getName(), currentHtmlParameter.getValue()); if (!cookieBack1.getFlags().contains("secure")) { extraInfo += ("\n" + Constant.messages.getString( "ascanbeta.sessionidsentinsecurely.alert.extrainfo.secureflagnotset")); } // and figure out the risk, depending on whether it is a login page int risk = Alert.RISK_LOW; if (loginUrl) { extraInfo += ("\n" + Constant.messages .getString("ascanbeta.sessionidsentinsecurely.alert.extrainfo.loginpage")); // login page, so higher risk risk = Alert.RISK_MEDIUM; } else { // not a login page.. lower risk risk = Alert.RISK_LOW; } String attack = Constant.messages.getString( "ascanbeta.sessionidsentinsecurely.alert.attack", currentHtmlParameter.getType(), currentHtmlParameter.getName()); String vulnname = Constant.messages.getString("ascanbeta.sessionidsentinsecurely.name"); String vulndesc = Constant.messages.getString("ascanbeta.sessionidsentinsecurely.desc"); String vulnsoln = Constant.messages.getString("ascanbeta.sessionidsentinsecurely.soln"); // call bingo with some extra info, indicating that the alert is // not specific to Session Fixation, but has its own title and description // (etc) // the alert here is "Session id sent insecurely", or words to that effect. bingo(risk, Alert.CONFIDENCE_MEDIUM, vulnname, vulndesc, getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getName(), attack, extraInfo, vulnsoln, getBaseMsg()); if (log.isDebugEnabled()) { String logMessage = MessageFormat.format( "A session identifier in {2} field: [{3}] may be sent " + "via an insecure mechanism at [{0}] URL [{1}]", getBaseMsg().getRequestHeader().getMethod(), getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getType(), currentHtmlParameter.getName()); log.debug(logMessage); } // Note: do NOT continue to the next field at this point.. // since we still need to check for Session Fixation. } ////////////////////////////////////////////////////////////////////// // Check 2: is the session cookie that was set accessible to Javascript? // If so, alert this fact too if (!cookieBack1.getFlags().contains("httponly") && loginUrl) { // pass the original param value here, not the new value, since we're // displaying the session id exposed in the original message String extraInfo = Constant.messages.getString( "ascanbeta.sessionidaccessiblebyjavascript.alert.extrainfo", currentHtmlParameter.getType(), currentHtmlParameter.getName(), currentHtmlParameter.getValue()); String attack = Constant.messages.getString( "ascanbeta.sessionidaccessiblebyjavascript.alert.attack", currentHtmlParameter.getType(), currentHtmlParameter.getName()); String vulnname = Constant.messages .getString("ascanbeta.sessionidaccessiblebyjavascript.name"); String vulndesc = Constant.messages .getString("ascanbeta.sessionidaccessiblebyjavascript.desc"); String vulnsoln = Constant.messages .getString("ascanbeta.sessionidaccessiblebyjavascript.soln"); extraInfo += ("\n" + Constant.messages .getString("ascanbeta.sessionidaccessiblebyjavascript.alert.extrainfo.loginpage")); // call bingo with some extra info, indicating that the alert is // not specific to Session Fixation, but has its own title and description // (etc) // the alert here is "Session id accessible in Javascript", or words to that // effect. bingo(Alert.RISK_LOW, Alert.CONFIDENCE_MEDIUM, vulnname, vulndesc, getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getName(), attack, extraInfo, vulnsoln, getBaseMsg()); if (log.isDebugEnabled()) { String logMessage = MessageFormat.format( "A session identifier in [{0}] URL [{1}] {2} field: " + "[{3}] may be accessible to JavaScript", getBaseMsg().getRequestHeader().getMethod(), getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getType(), currentHtmlParameter.getName()); log.debug(logMessage); } // Note: do NOT continue to the next field at this point.. // since we still need to check for Session Fixation. } ////////////////////////////////////////////////////////////////////// // Check 3: is the session cookie set to expire soon? when the browser session // closes? never? // the longer the session cookie is valid, the greater the risk. alert it // accordingly String cookieBack1Expiry = null; int sessionExpiryRiskLevel; String sessionExpiryDescription = null; // check for the Expires header for (Iterator<String> i = cookieBack1.getFlags().iterator(); i.hasNext();) { String cookieBack1Flag = i.next(); // if ( this.debugEnabled ) log.debug("Cookie back 1 flag (checking for // Expires): "+ cookieBack1Flag); // match in a case insensitive manner. never know what case various web // servers are going to send back. // if (cookieBack1Flag.matches("(?i)expires=.*")) { if (cookieBack1Flag.toLowerCase(Locale.ENGLISH).startsWith("expires=")) { String[] cookieBack1FlagValues = cookieBack1Flag.split("="); if (cookieBack1FlagValues.length > 1) { if (this.debugEnabled) log.debug("Cookie Expiry: " + cookieBack1FlagValues[1]); cookieBack1Expiry = cookieBack1FlagValues[1]; // the Date String sessionExpiryDescription = cookieBack1FlagValues[1]; // the Date String cookieBack1ExpiryDate = DateUtil.parseDate(cookieBack1Expiry); // the actual Date } } } // also check for the Max-Age header, which overrides the Expires header. // WARNING: this Directive is reported to be ignored by IE, so if both Expires // and Max-Age are present // and we report based on the Max-Age value, but the user is using IE, then the // results reported // by us here may be different from those actually experienced by the user! (we // use Max-Age, IE uses Expires) for (Iterator<String> i = cookieBack1.getFlags().iterator(); i.hasNext();) { String cookieBack1Flag = i.next(); // if ( this.debugEnabled ) log.debug("Cookie back 1 flag (checking for // Max-Age): "+ cookieBack1Flag); // match in a case insensitive manner. never know what case various web // servers are going to send back. if (cookieBack1Flag.toLowerCase(Locale.ENGLISH).startsWith("max-age=")) { String[] cookieBack1FlagValues = cookieBack1Flag.split("="); if (cookieBack1FlagValues.length > 1) { // now the Max-Age value is the number of seconds relative to the // time the browser received the cookie // (as stored in cookieBack1TimeReceived) if (this.debugEnabled) log.debug("Cookie Max Age: " + cookieBack1FlagValues[1]); long cookie1DropDeadMS = cookieBack1TimeReceived + (Long.parseLong(cookieBack1FlagValues[1]) * 1000); cookieBack1ExpiryDate = new Date(cookie1DropDeadMS); // the actual Date the cookie // expires (by Max-Age) cookieBack1Expiry = DateUtil.formatDate(cookieBack1ExpiryDate, DateUtil.PATTERN_RFC1123); sessionExpiryDescription = cookieBack1Expiry; // needs to the Date String } } } String sessionExpiryRiskDescription = null; // check the Expiry/Max-Age details garnered (if any) // and figure out the risk, depending on whether it is a login page // and how long the session will live before expiring if (cookieBack1ExpiryDate == null) { // session expires when the browser closes.. rate this as medium risk? sessionExpiryRiskLevel = Alert.RISK_MEDIUM; sessionExpiryRiskDescription = "ascanbeta.sessionidexpiry.browserclose"; sessionExpiryDescription = Constant.messages.getString(sessionExpiryRiskDescription); } else { long datediffSeconds = (cookieBack1ExpiryDate.getTime() - cookieBack1TimeReceived) / 1000; long anHourSeconds = 3600; long aDaySeconds = anHourSeconds * 24; long aWeekSeconds = aDaySeconds * 7; if (datediffSeconds < 0) { if (this.debugEnabled) log.debug("The session cookie has expired already"); sessionExpiryRiskDescription = "ascanbeta.sessionidexpiry.timeexpired"; sessionExpiryRiskLevel = Alert.RISK_INFO; // no risk.. the cookie has expired already } else if (datediffSeconds > aWeekSeconds) { if (this.debugEnabled) log.debug("The session cookie is set to last for more than a week!"); sessionExpiryRiskDescription = "ascanbeta.sessionidexpiry.timemorethanoneweek"; sessionExpiryRiskLevel = Alert.RISK_HIGH; } else if (datediffSeconds > aDaySeconds) { if (this.debugEnabled) log.debug("The session cookie is set to last for more than a day"); sessionExpiryRiskDescription = "ascanbeta.sessionidexpiry.timemorethanoneday"; sessionExpiryRiskLevel = Alert.RISK_MEDIUM; } else if (datediffSeconds > anHourSeconds) { if (this.debugEnabled) log.debug("The session cookie is set to last for more than an hour"); sessionExpiryRiskDescription = "ascanbeta.sessionidexpiry.timemorethanonehour"; sessionExpiryRiskLevel = Alert.RISK_LOW; } else { if (this.debugEnabled) log.debug("The session cookie is set to last for less than an hour!"); sessionExpiryRiskDescription = "ascanbeta.sessionidexpiry.timelessthanonehour"; sessionExpiryRiskLevel = Alert.RISK_INFO; } } if (!loginUrl) { // decrement the risk if it's not a login page sessionExpiryRiskLevel--; } // alert it if the default session expiry risk level is more than informational if (sessionExpiryRiskLevel > Alert.RISK_INFO) { // pass the original param value here, not the new value String cookieReceivedTime = cookieBack1Expiry = DateUtil .formatDate(new Date(cookieBack1TimeReceived), DateUtil.PATTERN_RFC1123); String extraInfo = Constant.messages.getString("ascanbeta.sessionidexpiry.alert.extrainfo", currentHtmlParameter.getType(), currentHtmlParameter.getName(), currentHtmlParameter.getValue(), sessionExpiryDescription, cookieReceivedTime); String attack = Constant.messages.getString("ascanbeta.sessionidexpiry.alert.attack", currentHtmlParameter.getType(), currentHtmlParameter.getName()); String vulnname = Constant.messages.getString("ascanbeta.sessionidexpiry.name"); String vulndesc = Constant.messages.getString("ascanbeta.sessionidexpiry.desc"); String vulnsoln = Constant.messages.getString("ascanbeta.sessionidexpiry.soln"); if (loginUrl) { extraInfo += ("\n" + Constant.messages .getString("ascanbeta.sessionidexpiry.alert.extrainfo.loginpage")); } // call bingo with some extra info, indicating that the alert is // not specific to Session Fixation, but has its own title and description // (etc) // the alert here is "Session Id Expiry Time is excessive", or words to that // effect. bingo(sessionExpiryRiskLevel, Alert.CONFIDENCE_MEDIUM, vulnname, vulndesc, getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getName(), attack, extraInfo, vulnsoln, getBaseMsg()); if (log.isDebugEnabled()) { String logMessage = MessageFormat.format( "A session identifier in [{0}] URL [{1}] {2} field: " + "[{3}] may be accessed until [{4}], unless the session is destroyed.", getBaseMsg().getRequestHeader().getMethod(), getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getType(), currentHtmlParameter.getName(), sessionExpiryDescription); log.debug(logMessage); } // Note: do NOT continue to the next field at this point.. // since we still need to check for Session Fixation. } if (!loginUrl) { // not a login page.. skip continue; } //////////////////////////////////////////////////////////////////////////////////////////// /// Message 2 - processing starts here //////////////////////////////////////////////////////////////////////////////////////////// // so now that we know the URL responds with 200 (OK), and that it sets a // cookie, lets re-issue the original request, // but lets add in the new (valid) session cookie that was just issued. // we will re-send it. the aim is then to see if it accepts the cookie (BAD, in // some circumstances), // or if it issues a new session cookie (GOOD, in most circumstances) if (this.debugEnabled) log.debug("A Cookie was set by the URL for the correct param, when param [" + currentHtmlParameter.getName() + "] was set to NULL: " + cookieBack1); // use a copy of msg2Initial, since it has already had the correct cookie // removed in the request.. // do NOT use msg2Initial itself, as this will cause both requests in the GUI to // show the modified data.. // finally send the second message, and see how it comes back. HttpMessage msg2Initial = msg1Initial.cloneRequest(); TreeSet<HtmlParameter> cookieParams2Set = msg2Initial.getRequestHeader().getCookieParams(); cookieParams2Set.add(cookieBack1); msg2Initial.setCookieParams(cookieParams2Set); // resend the copy of the initial message, but with the valid session cookie // added in, to see if it is accepted // do not automatically follow redirects, as we need to check these for cookies // being set. sendAndReceive(msg2Initial, false, false); // create a copy of msg2Initial to play with to handle redirects (if any). // we use a copy because if we change msg2Initial itself, it messes the URL and // params displayed on the GUI. HttpMessage temp2 = msg2Initial; HttpMessage msg2Final = msg2Initial; HtmlParameter cookieBack2Previous = cookieBack1; HtmlParameter cookieBack2 = getResponseCookie(msg2Initial, currentHtmlParameter.getName()); int redirectsFollowed2 = 0; while (HttpStatusCode.isRedirection(temp2.getResponseHeader().getStatusCode())) { // clone the previous message boolean secure2 = temp2.getRequestHeader().isSecure(); temp2 = temp2.cloneAll(); redirectsFollowed2++; if (redirectsFollowed2 > 10) { throw new Exception("Too many redirects were specified in the second message"); } // create a new URI from the absolute location returned, and interpret it as // escaped // note that the standard says that the Location returned should be // absolute, but it ain't always so... URI newLocation = new URI(temp2.getResponseHeader().getHeader(HttpHeader.LOCATION), true); // and follow the forward url // need to clear the params (which would come from the initial POST, // otherwise) temp2.getRequestHeader().setGetParams(new TreeSet<HtmlParameter>()); temp2.setRequestBody(""); temp2.setResponseBody(""); // make sure no values accidentally carry from one iteration to // the next try { temp2.getRequestHeader().setURI(newLocation); } catch (Exception e) { // the Location field contents may not be standards compliant. Lets // generate a uri to use as a workaround where a relative path was // given instead of an absolute one URI newLocationWorkaround = new URI(temp2.getRequestHeader().getURI(), temp2.getResponseHeader().getHeader(HttpHeader.LOCATION), true); // try again, except this time, if it fails, don't try to handle it if (this.debugEnabled) log.debug("The Location [" + newLocation + "] specified in a redirect was not valid. Trying workaround url [" + newLocationWorkaround + "]"); temp2.getRequestHeader().setURI(newLocationWorkaround); } temp2.getRequestHeader().setSecure(secure2); temp2.getRequestHeader().setMethod(HttpRequestHeader.GET); temp2.getRequestHeader().setContentLength(0); // since we send a GET, the body will be 0 long if (cookieBack2 != null) { // if the previous request sent back a cookie, we need to set that // cookie when following redirects, as a browser would // also make sure to delete the previous value set for the cookie value if (this.debugEnabled) { log.debug("Deleting old cookie [" + cookieBack2Previous + "], and adding in cookie [" + cookieBack2 + "] for a redirect"); } TreeSet<HtmlParameter> forwardCookieParams = temp2.getRequestHeader().getCookieParams(); forwardCookieParams.remove(cookieBack2Previous); forwardCookieParams.add(cookieBack2); temp2.getRequestHeader().setCookieParams(forwardCookieParams); } sendAndReceive(temp2, false, false); // do NOT automatically redirect.. handle redirects here // handle any cookies set from following redirects that override the cookie // set in the redirect itself (if any) // note that this will handle the case where a latter cookie unsets one set // earlier. HtmlParameter cookieBack2Temp = getResponseCookie(temp2, currentHtmlParameter.getName()); if (cookieBack2Temp != null) { cookieBack2Previous = cookieBack2; cookieBack2 = cookieBack2Temp; } // reset the "final" version of message2 to use the final response in the // chain msg2Final = temp2; } if (this.debugEnabled) log.debug("Done following redirects"); // final result was non-200, no point in continuing. Bale out. if (msg2Final.getResponseHeader().getStatusCode() != HttpStatusCode.OK) { if (this.debugEnabled) log.debug( "Got a non-200 response code [" + msg2Final.getResponseHeader().getStatusCode() + "] when sending [" + msg2Initial.getRequestHeader().getURI() + "] with a borrowed cookie (or by following a redirect) for param [" + currentHtmlParameter.getName() + "]"); continue; // to next parameter } // and what we've been waiting for.. do we get a *different* cookie being set in // the response of message 2?? // or do we get a new cookie back at all? // No cookie back => the borrowed cookie was accepted. Not ideal // Cookie back, but same as the one we sent in => the borrowed cookie was // accepted. Not ideal if ((cookieBack2 == null) || cookieBack2.getValue().equals(cookieBack1.getValue())) { // no cookie back, when a borrowed cookie is in use.. suspicious! // use the cookie extrainfo message, which is specific to the case of // cookies // pretty much everything else is generic to all types of Session Fixation // vulnerabilities String extraInfo = Constant.messages.getString( "ascanbeta.sessionfixation.alert.cookie.extrainfo", currentHtmlParameter.getName(), cookieBack1.getValue(), (cookieBack2 == null ? "NULL" : cookieBack2.getValue())); String attack = Constant.messages.getString("ascanbeta.sessionfixation.alert.attack", currentHtmlParameter.getType(), currentHtmlParameter.getName()); if (loginUrl) { extraInfo += ("\n" + Constant.messages .getString("ascanbeta.sessionfixation.alert.cookie.extrainfo.loginpage")); } bingo(Alert.RISK_INFO, Alert.CONFIDENCE_MEDIUM, msg2Initial.getRequestHeader().getURI().getURI(), currentHtmlParameter.getName(), attack, extraInfo, msg2Initial); logSessionFixation(msg2Initial, currentHtmlParameter.getType().toString(), currentHtmlParameter.getName()); } continue; // jump to the next iteration of the loop (ie, the next parameter) } // end of the cookie code. // start of the url parameter code // note that this actually caters for // - actual URL parameters // - pseudo URL parameters, where the sessionid was in the path portion of the URL, // in conjunction with URL re-writing if (currentHtmlParameter.getType().equals(HtmlParameter.Type.url)) { boolean isPseudoUrlParameter = false; // is this "url parameter" actually a url parameter, or was it // path of the path (+url re-writing)? String possibleSessionIdIssuedForUrlParam = null; // remove the named url parameter from the request.. TreeSet<HtmlParameter> urlRequestParams = msg1Initial.getUrlParams(); // get parameters? if (!urlRequestParams.remove(currentHtmlParameter)) { isPseudoUrlParameter = true; // was not removed because it was a pseudo Url parameter, not a real url // parameter.. (so it would not be in the url params) // in this case, we will need to "rewrite" (ie hack) the URL path to remove // the pseudo url parameter portion // ie, we need to remove the ";jsessionid=<sessionid>" bit from the path // (assuming the current field is named 'jsessionid') // and replace it with ";jsessionid=" (ie, we nullify the possible "session" // parameter in the hope that a new session will be issued) // then we continue as usual to see if the URL is vulnerable to a Session // Fixation issue // Side note: quote the string to search for, and the replacement, so that // regex special characters are treated as literals String hackedUrl = requestUrl.replaceAll( Pattern.quote(";" + currentHtmlParameter.getName() + "=" + currentHtmlParameter.getValue()), Matcher.quoteReplacement(";" + currentHtmlParameter.getName() + "=")); if (this.debugEnabled) log.debug("Removing the pseudo URL parameter from [" + requestUrl + "]: [" + hackedUrl + "]"); // Note: the URL is not escaped. Handle it. msg1Initial.getRequestHeader().setURI(new URI(hackedUrl, false)); } msg1Initial.setGetParams(urlRequestParams); // url parameters // send the message, minus the value for the current parameter, and see how it // comes back. // Note: automatically follow redirects.. no need to look at any intermediate // responses. // this was only necessary for cookie-based session implementations sendAndReceive(msg1Initial); // if non-200 on the response for message 1, no point in continuing. Bale out. if (msg1Initial.getResponseHeader().getStatusCode() != HttpStatusCode.OK) { if (this.debugEnabled) log.debug("Got a non-200 response code [" + msg1Initial.getResponseHeader().getStatusCode() + "] when sending [" + msg1Initial.getRequestHeader().getURI() + "] with param [" + currentHtmlParameter.getName() + "] = NULL (possibly somewhere in the redirects)"); continue; } // now parse the HTML response for urls that contain the same parameter name, // and look at the values for that parameter // if no values are found for the parameter, then // 1) we are messing with the wrong field, or // 2) the app doesn't do sessions // either way, there is not much point in continuing to look at this field.. // parse out links in HTML (assume for a moment that all the URLs are in links) // this gives us a map of parameter value for the current parameter, to the // number of times it was encountered in links in the HTML SortedMap<String, Integer> parametersInHTMLURls = getParameterValueCountInHtml( msg1Initial.getResponseBody().toString(), currentHtmlParameter.getName(), isPseudoUrlParameter); if (this.debugEnabled) log.debug("The count of the various values of the [" + currentHtmlParameter.getName() + "] parameters in urls in the result of retrieving the url with a null value for parameter [" + currentHtmlParameter.getName() + "]: " + parametersInHTMLURls); if (parametersInHTMLURls.isEmpty()) { // setting the param to NULL did not cause any new values to be generated // for it in the output.. // so either.. // it is not a session field, or // it is a session field, but a session is only issued on authentication, // and this is not an authentication url // the app doesn't do sessions (etc) // either way, the parameter/url combo is not vulnerable, so continue with // the next parameter if (this.debugEnabled) log.debug("The URL parameter [" + currentHtmlParameter.getName() + "] was NOT set in any links in the response, when " + (isPseudoUrlParameter ? "pseudo/URL rewritten" : "") + " URL param [" + currentHtmlParameter.getName() + "] was set to NULL in the request, so it is likely not a session id field"); continue; // to the next parameter } else if (parametersInHTMLURls.size() == 1) { // the parameter was set to just one value in the output // so it's quite possible it is the session id field that we have been // looking for // caveat 1: check it is longer than 3 chars long, to remove false // positives.. // we assume here that a real session id will always be greater than 3 // characters long // caveat 2: the value we got back for the param must be different from the // value we // over-wrote with NULL (empty) in the first place, otherwise it is very // unlikely to // be a session id field possibleSessionIdIssuedForUrlParam = parametersInHTMLURls.firstKey(); // did we get back the same value we just nulled out in the original // request? // if so, use this to eliminate false positives, and to optimise. if (possibleSessionIdIssuedForUrlParam.equals(currentHtmlParameter.getValue())) { if (this.debugEnabled) log.debug((isPseudoUrlParameter ? "pseudo/URL rewritten" : "") + " URL param [" + currentHtmlParameter.getName() + "], when set to NULL, causes 1 distinct values to be set for it in URLs in the output, but the possible session id value [" + possibleSessionIdIssuedForUrlParam + "] is the same as the value we over-wrote with NULL. 'Sorry, kid. You got the gift, but it looks like you're waiting for something'"); continue; // to the next parameter } if (possibleSessionIdIssuedForUrlParam.length() > 3) { // raise an alert here on an exposed session id, even if it is not // subject to a session fixation vulnerability // log.info("The URL parameter ["+ currentHtmlParameter.getName() + "] // was set ["+ // parametersInHTMLURls.get(possibleSessionIdIssuedForUrlParam)+ "] // times to ["+ possibleSessionIdIssuedForUrlParam + "] in links in the // response, when "+ (isPseudoUrlParameter?"pseudo/URL rewritten":"")+ " // URL param ["+ currentHtmlParameter.getName() + "] was set to NULL in // the request. This likely indicates it is a session id field."); // pass the original param value here, not the new value, since we're // displaying the session id exposed in the original message String extraInfo = Constant.messages.getString( "ascanbeta.sessionidexposedinurl.alert.extrainfo", currentHtmlParameter.getType(), currentHtmlParameter.getName(), currentHtmlParameter.getValue()); String attack = Constant.messages .getString("ascanbeta.sessionidexposedinurl.alert.attack", (isPseudoUrlParameter ? "pseudo/URL rewritten " : "") + currentHtmlParameter.getType(), currentHtmlParameter.getName()); String vulnname = Constant.messages.getString("ascanbeta.sessionidexposedinurl.name"); String vulndesc = Constant.messages.getString("ascanbeta.sessionidexposedinurl.desc"); String vulnsoln = Constant.messages.getString("ascanbeta.sessionidexposedinurl.soln"); if (loginUrl) { extraInfo += ("\n" + Constant.messages .getString("ascanbeta.sessionidexposedinurl.alert.extrainfo.loginpage")); } // call bingo with some extra info, indicating that the alert is // not specific to Session Fixation, but has its own title and // description (etc) // the alert here is "Session id exposed in url", or words to that // effect. bingo(Alert.RISK_MEDIUM, Alert.CONFIDENCE_MEDIUM, vulnname, vulndesc, getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getName(), attack, extraInfo, vulnsoln, getBaseMsg()); if (log.isDebugEnabled()) { String logMessage = MessageFormat.format( "An exposed session identifier has been found at " + "[{0}] URL [{1}] on {2} field: [{3}]", getBaseMsg().getRequestHeader().getMethod(), getBaseMsg().getRequestHeader().getURI().getURI(), (isPseudoUrlParameter ? "pseudo " : "") + currentHtmlParameter.getType(), currentHtmlParameter.getName()); log.debug(logMessage); } // Note: do NOT continue to the next field at this point.. // since we still need to check for Session Fixation. } else { if (this.debugEnabled) log.debug((isPseudoUrlParameter ? "pseudo/URL rewritten" : "") + " URL param [" + currentHtmlParameter.getName() + "], when set to NULL, causes 1 distinct values to be set for it in URLs in the output, but the possible session id value [" + possibleSessionIdIssuedForUrlParam + "] is too short to be a real session id."); continue; // to the next parameter } } else { // strange scenario: setting the param to null causes multiple different // values to be set for it in the output // it could still be a session parameter, but we assume it is *not* a // session id field // log it, but assume it is not a session id if (this.debugEnabled) log.debug((isPseudoUrlParameter ? "pseudo/URL rewritten" : "") + " URL param [" + currentHtmlParameter.getName() + "], when set to NULL, causes [" + parametersInHTMLURls.size() + "] distinct values to be set for it in URLs in the output. Assuming it is NOT a session id as a consequence. This could be a false negative"); continue; // to the next parameter } //////////////////////////////////////////////////////////////////////////////////////////// /// Message 2 - processing starts here //////////////////////////////////////////////////////////////////////////////////////////// // we now have a plausible session id field to play with, so set it to a // borrowed value. // ie: lets re-send the request, but add in the new (valid) session value that // was just issued. // the aim is then to see if it accepts the session without re-issuing the // session id (BAD, in some circumstances), // or if it issues a new session value (GOOD, in most circumstances) // and set the (modified) session for the second message // use a copy of msg2Initial, since it has already had the correct session // removed in the request.. // do NOT use msg2Initial itself, as this will cause both requests in the GUI to // show the modified data.. // finally send the second message, and see how it comes back. HttpMessage msg2Initial = msg1Initial.cloneRequest(); // set the parameter to the new session id value (in different manners, // depending on whether it is a real url param, or a pseudo url param) if (isPseudoUrlParameter) { // we need to "rewrite" (hack) the URL path to remove the pseudo url // parameter portion // id, we need to remove the ";jsessionid=<sessionid>" bit from the path // and replace it with ";jsessionid=" (ie, we nullify the possible "session" // parameter in the hope that a new session will be issued) // then we continue as usual to see if the URL is vulnerable to a Session // Fixation issue // Side note: quote the string to search for, and the replacement, so that // regex special characters are treated as literals String hackedUrl = requestUrl.replaceAll( Pattern.quote(";" + currentHtmlParameter.getName() + "=" + currentHtmlParameter.getValue()), Matcher.quoteReplacement(";" + currentHtmlParameter.getName() + "=" + possibleSessionIdIssuedForUrlParam)); if (this.debugEnabled) log.debug("Changing the pseudo URL parameter from [" + requestUrl + "]: [" + hackedUrl + "]"); // Note: the URL is not escaped msg2Initial.getRequestHeader().setURI(new URI(hackedUrl, false)); msg2Initial.setGetParams(msg1Initial.getUrlParams()); // restore the GET params } else { // do it via the normal url parameters TreeSet<HtmlParameter> urlRequestParams2 = msg2Initial.getUrlParams(); urlRequestParams2.add(new HtmlParameter(Type.url, currentHtmlParameter.getName(), possibleSessionIdIssuedForUrlParam)); msg2Initial.setGetParams(urlRequestParams2); // restore the GET params } // resend a copy of the initial message, but with the new valid session // parameter added in, to see if it is accepted // automatically follow redirects, which are irrelevant for the purposes of // testing URL parameters sendAndReceive(msg2Initial); // final result was non-200, no point in continuing. Bale out. if (msg2Initial.getResponseHeader().getStatusCode() != HttpStatusCode.OK) { if (this.debugEnabled) log.debug("Got a non-200 response code [" + msg2Initial.getResponseHeader().getStatusCode() + "] when sending [" + msg2Initial.getRequestHeader().getURI() + "] with a borrowed session (or by following a redirect) for param [" + currentHtmlParameter.getName() + "]"); continue; // next field! } // do the analysis on the parameters in link urls in the HTML output again to // see if the session id was regenerated SortedMap<String, Integer> parametersInHTMLURls2 = getParameterValueCountInHtml( msg2Initial.getResponseBody().toString(), currentHtmlParameter.getName(), isPseudoUrlParameter); if (this.debugEnabled) log.debug("The count of the various values of the [" + currentHtmlParameter.getName() + "] parameters in urls in the result of retrieving the url with a borrowed session value for parameter [" + currentHtmlParameter.getName() + "]: " + parametersInHTMLURls2); if (parametersInHTMLURls2.size() != 1) { // either no values, or multiple values, but not 1 value. For a session // that was regenerated, we would have expected to see // just 1 new value if (this.debugEnabled) log.debug("The HTML has spoken. [" + currentHtmlParameter.getName() + "] doesn't look like a session id field, because there are " + parametersInHTMLURls2.size() + " distinct values for this parameter in urls in the HTML output"); continue; } // there is but one value for this param in links in the HTML output. But is it // vulnerable to Session Fixation? Ie, is it the same parameter? String possibleSessionIdIssuedForUrlParam2 = parametersInHTMLURls2.firstKey(); if (possibleSessionIdIssuedForUrlParam2.equals(possibleSessionIdIssuedForUrlParam)) { // same sessionid used in the output.. so it is likely that we have a // SessionFixation issue.. // use the url param extrainfo message, which is specific to the case of url // parameters and url re-writing Session Fixation issue // pretty much everything else is generic to all types of Session Fixation // vulnerabilities String extraInfo = Constant.messages.getString( "ascanbeta.sessionfixation.alert.url.extrainfo", currentHtmlParameter.getName(), possibleSessionIdIssuedForUrlParam, possibleSessionIdIssuedForUrlParam2); String attack = Constant.messages.getString("ascanbeta.sessionfixation.alert.attack", (isPseudoUrlParameter ? "pseudo/URL rewritten " : "") + currentHtmlParameter.getType(), currentHtmlParameter.getName()); int risk = Alert.RISK_LOW; if (loginUrl) { extraInfo += ("\n" + Constant.messages .getString("ascanbeta.sessionfixation.alert.url.extrainfo.loginpage")); // login page, so higher risk risk = Alert.RISK_MEDIUM; } else { // not a login page.. lower risk risk = Alert.RISK_LOW; } bingo(risk, Alert.CONFIDENCE_MEDIUM, getBaseMsg().getRequestHeader().getURI().getURI(), currentHtmlParameter.getName(), attack, extraInfo, getBaseMsg()); logSessionFixation(getBaseMsg(), (isPseudoUrlParameter ? "pseudo " : "") + currentHtmlParameter.getType(), currentHtmlParameter.getName()); continue; // jump to the next iteration of the loop (ie, the next parameter) } else { // different sessionid used in the output.. so it is unlikely that we have a // SessionFixation issue.. // more likely that the Session is being re-issued for every single request, // or we have issues a login request, which // normally causes a session to be reissued if (this.debugEnabled) log.debug("The " + (isPseudoUrlParameter ? "pseudo/URL rewritten" : "") + " parameter [" + currentHtmlParameter.getName() + "] in url [" + getBaseMsg().getRequestHeader().getMethod() + "] [" + getBaseMsg().getRequestHeader().getURI() + "] changes with requests, and so it likely not vulnerable to Session Fixation"); } continue; // onto the next parameter } // end of the url parameter code. } // end of the for loop around the parameter list } catch (Exception e) { // Do not try to internationalise this.. we need an error message in any event.. // if it's in English, it's still better than not having it at all. log.error("An error occurred checking a url for Session Fixation issues", e); } }
From source file:org.testeditor.fixture.swt.SwtBotFixture.java
/** * Creates TestStructure Files in the filesystem of a fitnesse backend * system. This method doesn't use the api for that and does no * notifications to the test-editor or fitnsse server. * //from w w w . j a v a2 s .c o m * @param destinationTestStructure * full name of the new one * @return true on success * @throws IOException * on creation error. */ public boolean createTestStructureFiles(String destinationTestStructure) { String[] tsNameParts = destinationTestStructure.split("\\."); try { String destPath = getWorkspacePath() + File.separator + tsNameParts[0] + File.separator + "FitNesseRoot" + File.separator + destinationTestStructure.replaceAll("\\.", Matcher.quoteReplacement(File.separator)); Path tsDir = Files.createDirectories(Paths.get(destPath)); LOGGER.trace("Created: " + tsDir.toAbsolutePath()); String xml = "<?xml version=\"1.0\"?><properties><Edit>true</Edit><Files>true</Files><Properties>true</Properties><RecentChanges>true</RecentChanges><Refactor>true</Refactor><Search>true</Search><Test/><Versions>true</Versions><WhereUsed>true</WhereUsed></properties>"; Files.write(Paths.get(destPath, "properties.xml"), xml.getBytes()); return new File(tsDir.toFile(), "content.txt").createNewFile(); } catch (Exception e) { LOGGER.error("Error creating testobject from " + destinationTestStructure, e); } return false; }
From source file:au.org.ala.delta.key.Key.java
private void generateTypesetBracketedKey(BracketedKey bracketedKey, List<Character> includedCharacters, List<Item> includedItems, PrintFile typesetFile, boolean displayCharacterNumbers, boolean outputHtml, int numCharactersUsedInKey, int numTaxaUsedInKey, double avgLenKey, double avgCostKey, double maxLenKey, double maxCostKey) { StringBuilder typesetTextBuilder = new StringBuilder(); // Output start of file TypeSettingMark startFileMark = _context.getTypeSettingMark(MarkPosition.START_OF_FILE); typesetTextBuilder.append(startFileMark.getMarkText()); // Output any file heading text set using the PRINT COMMENT directive String headerText = _context.getTypeSettingFileHeaderText(); if (headerText != null) { typesetTextBuilder.append(_context.getTypeSettingFileHeaderText()); }/*from www .j a v a2 s. c o m*/ // Output key parameters TypeSettingMark parametersMark = _context.getTypeSettingMark(MarkPosition.PARAMETERS); String parametersText = parametersMark.getMarkText(); typesetTextBuilder.append(parametersText); for (BracketedKeyNode node : bracketedKey) { typesetTextBuilder .append(generateTypesetTextForBracketedKeyNode(node, outputHtml, displayCharacterNumbers)); } TypeSettingMark endKeyMark = _context.getTypeSettingMark(MarkPosition.END_OF_KEY); typesetTextBuilder.append(endKeyMark.getMarkText()); TypeSettingMark endFileMark = _context.getTypeSettingMark(MarkPosition.END_OF_FILE); typesetTextBuilder.append(endFileMark.getMarkText()); String typesetText = typesetTextBuilder.toString(); typesetText = typesetText.replaceAll("@nchar", Integer.toString(_context.getDataSet().getNumberOfCharacters())); typesetText = typesetText.replaceAll("@ncincl", Integer.toString(includedCharacters.size())); typesetText = typesetText.replaceAll("@ncinkey", Integer.toString(numCharactersUsedInKey)); typesetText = typesetText.replaceAll("@ntaxa", Integer.toString(_context.getDataSet().getMaximumNumberOfItems())); typesetText = typesetText.replaceAll("@ntincl", Integer.toString(includedItems.size())); typesetText = typesetText.replaceAll("@ntinkey", Integer.toString(numTaxaUsedInKey)); typesetText = typesetText.replaceAll("@rbase", formatDouble(_context.getRBase())); typesetText = typesetText.replaceAll("@abase", formatDouble(_context.getABase())); typesetText = typesetText.replaceAll("@reuse", formatDouble(_context.getReuse())); typesetText = typesetText.replaceAll("@varywt", formatDouble(_context.getVaryWt())); typesetText = typesetText.replaceAll("@nconf", Integer.toString(_context.getNumberOfConfirmatoryCharacters())); typesetText = typesetText.replaceAll("@avglen", formatDouble(avgLenKey)); typesetText = typesetText.replaceAll("@avgcost", formatDouble(avgCostKey)); typesetText = typesetText.replaceAll("@maxlen", formatDouble(maxLenKey)); typesetText = typesetText.replaceAll("@maxcost", formatDouble(maxCostKey)); List<Integer> includedCharacterNumbers = new ArrayList<Integer>(); for (Character ch : includedCharacters) { includedCharacterNumbers.add(ch.getCharacterId()); } List<Integer> includedItemNumbers = new ArrayList<Integer>(); for (Item it : includedItems) { includedItemNumbers.add(it.getItemNumber()); } // any backslashes that may occur in rangeSymbol need to be escaped // otherwise they will be omitted when we do // a String.replaceAll String rangeSymbol = Matcher .quoteReplacement(_context.getTypeSettingMark(MarkPosition.RANGE_SYMBOL).getMarkText()); typesetText = typesetText.replaceAll("@cmask", Utils.formatIntegersAsListOfRanges(includedCharacterNumbers, rangeSymbol)); typesetText = typesetText.replaceAll("@rel", KeyUtils.formatCharacterReliabilities(_context, ",", rangeSymbol)); typesetText = typesetText.replaceAll("@tmask", Utils.formatIntegersAsListOfRanges(includedItemNumbers, rangeSymbol)); typesetText = typesetText.replaceAll("@tabund", KeyUtils.formatCharacterReliabilities(_context, ",", rangeSymbol)); typesetText = typesetText.replaceAll("@preset", KeyUtils.formatPresetCharacters(_context)); // @preset - Preset characters. typesetFile.outputLine(typesetText); }
From source file:edu.harvard.iq.dvn.ingest.statdataio.impl.plugins.dta.DTAFileReader.java
private void decodeData(BufferedInputStream stream) throws IOException { dbgLog.fine("\n***** decodeData(): start *****"); if (stream == null) { throw new IllegalArgumentException("stream == null!"); }//from ww w . ja v a2s .com int nvar = (Integer) smd.getFileInformation().get("varQnty"); int nobs = (Integer) smd.getFileInformation().get("caseQnty"); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine("data diminsion[rxc]=(" + nobs + "," + nvar + ")"); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine("bytes per row=" + bytes_per_row + " bytes"); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine("variableTypelList=" + Arrays.deepToString(variableTypelList)); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine("StringVariableTable=" + StringVariableTable); FileOutputStream fileOutTab = null; PrintWriter pwout = null; // create a File object to save the tab-delimited data file File tabDelimitedDataFile = File.createTempFile("tempTabfile.", ".tab"); String tabDelimitedDataFileName = tabDelimitedDataFile.getAbsolutePath(); // save the temp file name in the metadata object smd.getFileInformation().put("tabDelimitedDataFileLocation", tabDelimitedDataFileName); fileOutTab = new FileOutputStream(tabDelimitedDataFile); pwout = new PrintWriter(new OutputStreamWriter(fileOutTab, "utf8"), true); // data storage // Object[][] dataTable = new Object[nobs][nvar]; // for later variable-wise calculations of statistics // dataTable2 sotres cut-out data columnwise Object[][] dataTable2 = new Object[nvar][nobs]; String[][] dateFormat = new String[nvar][nobs]; for (int i = 0; i < nobs; i++) { byte[] dataRowBytes = new byte[bytes_per_row]; Object[] dataRow = new Object[nvar]; int nbytes = stream.read(dataRowBytes, 0, bytes_per_row); if (nbytes == 0) { String errorMessage = "reading data: no data were read at(" + i + "th row)"; throw new IOException(errorMessage); } // decoding each row int byte_offset = 0; for (int columnCounter = 0; columnCounter < variableTypelList.length; columnCounter++) { Integer varType = variableTypeMap.get(variableTypelList[columnCounter]); String variableFormat = variableFormats[columnCounter]; boolean isDateTimeDatum = isDateTimeDatumList[columnCounter]; switch (varType != null ? varType : 256) { case -5: // Byte case // note: 1 byte signed byte byte_datum = dataRowBytes[byte_offset]; if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column byte =" + byte_datum); if (byte_datum >= BYTE_MISSING_VALUE) { if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column byte MV=" + byte_datum); dataRow[columnCounter] = MissingValueForTextDataFileNumeric; dataTable2[columnCounter][i] = null; //use null reference to indicate missing value in data that is passed to UNF } else { dataRow[columnCounter] = byte_datum; dataTable2[columnCounter][i] = byte_datum; } byte_offset++; break; case -4: // Stata-int (=java's short: 2byte) case // note: 2-byte signed int, not java's int ByteBuffer int_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 2); if (isLittleEndian) { int_buffer.order(ByteOrder.LITTLE_ENDIAN); } short short_datum = int_buffer.getShort(); if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column stata int =" + short_datum); if (short_datum >= INT_MISSIG_VALUE) { if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column stata long missing value=" + short_datum); dataTable2[columnCounter][i] = null; //use null reference to indicate missing value in data that is passed to UNF if (isDateTimeDatum) { dataRow[columnCounter] = MissingValueForTextDataFileString; } else { dataRow[columnCounter] = MissingValueForTextDataFileNumeric; } } else { if (isDateTimeDatum) { DecodedDateTime ddt = decodeDateTimeData("short", variableFormat, Short.toString(short_datum)); if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format=" + ddt.format); dataRow[columnCounter] = ddt.decodedDateTime; dateFormat[columnCounter][i] = ddt.format; dataTable2[columnCounter][i] = dataRow[columnCounter]; } else { dataTable2[columnCounter][i] = short_datum; dataRow[columnCounter] = short_datum; } } byte_offset += 2; break; case -3: // stata-Long (= java's int: 4 byte) case // note: 4-byte singed, not java's long dbgLog.fine("DATreader: stata long"); ByteBuffer long_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 4); if (isLittleEndian) { long_buffer.order(ByteOrder.LITTLE_ENDIAN); } int int_datum = long_buffer.getInt(); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine(i + "-th row " + columnCounter + "=th column stata long =" + int_datum); if (int_datum >= LONG_MISSING_VALUE) { if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine(i + "-th row " + columnCounter + "=th column stata long missing value=" + int_datum); dataTable2[columnCounter][i] = null; //use null reference to indicate missing value in data that is passed to UNF if (isDateTimeDatum) { dataRow[columnCounter] = MissingValueForTextDataFileString; } else { dataRow[columnCounter] = MissingValueForTextDataFileNumeric; } } else { if (isDateTimeDatum) { DecodedDateTime ddt = decodeDateTimeData("int", variableFormat, Integer.toString(int_datum)); if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format=" + ddt.format); dataRow[columnCounter] = ddt.decodedDateTime; dateFormat[columnCounter][i] = ddt.format; dataTable2[columnCounter][i] = dataRow[columnCounter]; } else { dataTable2[columnCounter][i] = int_datum; dataRow[columnCounter] = int_datum; } } byte_offset += 4; break; case -2: // float case // note: 4-byte ByteBuffer float_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 4); if (isLittleEndian) { float_buffer.order(ByteOrder.LITTLE_ENDIAN); } float float_datum = float_buffer.getFloat(); if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column float =" + float_datum); if (FLOAT_MISSING_VALUE_SET.contains(float_datum)) { if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column float missing value=" + float_datum); dataTable2[columnCounter][i] = null; //use null reference to indicate missing value in data that is passed to UNF if (isDateTimeDatum) { dataRow[columnCounter] = MissingValueForTextDataFileString; } else { dataRow[columnCounter] = MissingValueForTextDataFileNumeric; } } else { if (isDateTimeDatum) { DecodedDateTime ddt = decodeDateTimeData("float", variableFormat, doubleNumberFormatter.format(float_datum)); if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format=" + ddt.format); dataRow[columnCounter] = ddt.decodedDateTime; dateFormat[columnCounter][i] = ddt.format; dataTable2[columnCounter][i] = dataRow[columnCounter]; } else { dataTable2[columnCounter][i] = float_datum; dataRow[columnCounter] = float_datum; } } byte_offset += 4; break; case -1: // double case // note: 8-byte ByteBuffer double_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 8); if (isLittleEndian) { double_buffer.order(ByteOrder.LITTLE_ENDIAN); } double double_datum = double_buffer.getDouble(); if (DOUBLE_MISSING_VALUE_SET.contains(double_datum)) { dataTable2[columnCounter][i] = null; //use null reference to indicate missing value in data that is passed to UNF if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column double missing value=" + double_datum); if (isDateTimeDatum) { dataRow[columnCounter] = MissingValueForTextDataFileString; } else { dataRow[columnCounter] = MissingValueForTextDataFileNumeric; } } else { if (isDateTimeDatum) { DecodedDateTime ddt = decodeDateTimeData("double", variableFormat, doubleNumberFormatter.format(double_datum)); if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format=" + ddt.format); dataRow[columnCounter] = ddt.decodedDateTime; dateFormat[columnCounter][i] = ddt.format; dataTable2[columnCounter][i] = dataRow[columnCounter]; } else { dataTable2[columnCounter][i] = double_datum; dataRow[columnCounter] = doubleNumberFormatter.format(double_datum); } } byte_offset += 8; break; case 0: // String case int strVarLength = StringVariableTable.get(columnCounter); String raw_datum = new String( Arrays.copyOfRange(dataRowBytes, byte_offset, (byte_offset + strVarLength)), "ISO-8859-1"); String string_datum = getNullStrippedString(raw_datum); if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column string =" + string_datum); if (string_datum.equals("")) { if (dbgLog.isLoggable(Level.FINER)) dbgLog.finer(i + "-th row " + columnCounter + "=th column string missing value=" + string_datum); dataRow[columnCounter] = MissingValueForTextDataFileString; dataTable2[columnCounter][i] = null; //use null reference to indicate missing value in data that is passed to UNF } else { String escapedString = string_datum.replaceAll("\"", Matcher.quoteReplacement("\\\"")); /* * Fixing the bug we've had in the Stata reader for * a longest time: new lines and tabs need to * be escaped too - otherwise it breaks our * TAB file structure! -- L.A. */ escapedString = escapedString.replaceAll("\t", Matcher.quoteReplacement("\\t")); escapedString = escapedString.replaceAll("\n", Matcher.quoteReplacement("\\n")); escapedString = escapedString.replaceAll("\r", Matcher.quoteReplacement("\\r")); // the escaped version of the string will be // stored in the tab file: dataRow[columnCounter] = "\"" + escapedString + "\""; // but note that the "raw" version of it is // used for the UNF: dataTable2[columnCounter][i] = string_datum; } byte_offset += strVarLength; break; default: dbgLog.fine("unknown variable type found"); String errorMessage = "unknow variable Type found at data section"; throw new InvalidObjectException(errorMessage); } // switch } // for-columnCounter // dump the row of data to the external file pwout.println(StringUtils.join(dataRow, "\t")); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine(i + "-th row's data={" + StringUtils.join(dataRow, ",") + "};"); } // for- i (row) pwout.close(); if (dbgLog.isLoggable(Level.FINER)) { dbgLog.finer("\ndataTable2(variable-wise):\n"); dbgLog.finer(Arrays.deepToString(dataTable2)); dbgLog.finer("\ndateFormat(variable-wise):\n"); dbgLog.finer(Arrays.deepToString(dateFormat)); } if (dbgLog.isLoggable(Level.FINE)) { dbgLog.fine("variableTypelList:\n" + Arrays.deepToString(variableTypelList)); dbgLog.fine("variableTypelListFinal:\n" + Arrays.deepToString(variableTypelListFinal)); } String[] unfValues = new String[nvar]; for (int j = 0; j < nvar; j++) { String variableType_j = variableTypelListFinal[j]; unfValues[j] = getUNF(dataTable2[j], dateFormat[j], variableType_j, unfVersionNumber, j); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine(j + "th unf value" + unfValues[j]); } if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine("unf set:\n" + Arrays.deepToString(unfValues)); fileUnfValue = UNF5Util.calculateUNF(unfValues); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine("file-unf=" + fileUnfValue); stataDataSection.setUnf(unfValues); stataDataSection.setFileUnf(fileUnfValue); smd.setVariableUNF(unfValues); smd.getFileInformation().put("fileUNF", fileUnfValue); if (dbgLog.isLoggable(Level.FINE)) dbgLog.fine("unf values:\n" + unfValues); stataDataSection.setData(dataTable2); // close the stream dbgLog.fine("***** decodeData(): end *****\n\n"); }
From source file:au.org.ala.delta.key.Key.java
private String generateTypesetTextForBracketedKeyNode(BracketedKeyNode node, boolean outputHtml, boolean displayCharacterNumbers) { // @node - Node number. // @from - Previous node. // @to - Next node. // @state - feature/state text. // @nrow - number of "destinations" for the current node. CharacterFormatter typesetCharFormatter = new CharacterFormatter(false, CommentStrippingMode.STRIP_ALL, AngleBracketHandlingMode.REMOVE, false, true); typesetCharFormatter.setRtfToHtml(outputHtml); ItemFormatter typesetItemFormatter = new ItemFormatter(false, CommentStrippingMode.STRIP_ALL, AngleBracketHandlingMode.REMOVE, false, false, true); typesetItemFormatter.setRtfToHtml(outputHtml); // Need to count the number of destinations, as multiple taxa identified // by the one line are counted as distinct destinations. int numDestinations = 0; StringBuilder nodeTextBuilder = new StringBuilder(); TypeSettingMark firstLineMark;/*from ww w.j ava 2 s .c o m*/ if (node.getNodeNumber() == 1) { firstLineMark = _context.getTypeSettingMark(MarkPosition.FIRST_LEAD_OF_FIRST_NODE); } else { firstLineMark = _context.getTypeSettingMark(MarkPosition.FIRST_LEAD_OF_NODE); } TypeSettingMark subsequentLineMark = _context.getTypeSettingMark(MarkPosition.SUBSEQUENT_LEAD_OF_NODE); TypeSettingMark firstTaxonDestinationMark = _context .getTypeSettingMark(MarkPosition.FIRST_DESTINATION_OF_LEAD); TypeSettingMark subsequentTaxonDestinationMark = _context .getTypeSettingMark(MarkPosition.SUBSEQUENT_DESTINATION_OF_LEAD); TypeSettingMark afterTaxonNamesMark = _context.getTypeSettingMark(MarkPosition.AFTER_TAXON_NAME); TypeSettingMark nodeNumberDestinationMark = _context .getTypeSettingMark(MarkPosition.DESTINATION_OF_LEAD_NODE); TypeSettingMark afterNodeMark = _context.getTypeSettingMark(MarkPosition.AFTER_NODE); for (int i = 0; i < node.getNumberOfLines(); i++) { StringBuilder lineTextBuilder = new StringBuilder(); List<MultiStateAttribute> attributesForLine = node.getAttributesForLine(i); Object destinationForLine = node.getDestinationForLine(i); StringBuilder attributesTextBuilder = new StringBuilder(); for (int j = 0; j < attributesForLine.size(); j++) { MultiStateAttribute attr = attributesForLine.get(j); if (displayCharacterNumbers) { attributesTextBuilder.append("("); attributesTextBuilder.append(attr.getCharacter().getCharacterId()); attributesTextBuilder.append(") "); } attributesTextBuilder.append(typesetCharFormatter.formatCharacterDescription(attr.getCharacter())); attributesTextBuilder.append(" "); attributesTextBuilder.append(typesetCharFormatter.formatState(attr.getCharacter(), attr.getPresentStates().iterator().next())); // Don't put a semicolon/space after the last attribute // description if (j < attributesForLine.size() - 1) { attributesTextBuilder.append("; "); } } if (i == 0) { lineTextBuilder.append(firstLineMark.getMarkText()); } else { lineTextBuilder.append(subsequentLineMark.getMarkText()); } if (destinationForLine instanceof Integer) { int intDestination = (Integer) destinationForLine; String destinationText = nodeNumberDestinationMark.getMarkText(); destinationText = destinationText.replaceAll("@to", Integer.toString(intDestination)); lineTextBuilder.append(destinationText); numDestinations++; } else { List<Item> destinationTaxa = (List<Item>) destinationForLine; for (int j = 0; j < destinationTaxa.size(); j++) { numDestinations++; Item taxon = destinationTaxa.get(j); String formattedTaxonDescription = typesetItemFormatter.formatItemDescription(taxon); // Any backslashes in taxon description (from RTF // formatting) need to be escaped, // otherwise they will be omitted when we do a // String.replaceAll formattedTaxonDescription = Matcher.quoteReplacement(formattedTaxonDescription); String destinationText; if (j == 0) { destinationText = firstTaxonDestinationMark.getMarkText(); } else { destinationText = subsequentTaxonDestinationMark.getMarkText(); } destinationText = destinationText.replaceAll("@to", formattedTaxonDescription); lineTextBuilder.append(destinationText); } lineTextBuilder.append(afterTaxonNamesMark.getMarkText()); } String lineText = lineTextBuilder.toString(); // Need to escape any backslashes in attributes text (from RTF // formatting) otherwise they will be omitted when we do a // String.replaceAll() String attributesText = attributesTextBuilder.toString(); attributesText = Matcher.quoteReplacement(attributesText); lineText = lineText.replaceAll("@state", attributesText); nodeTextBuilder.append(lineText); } nodeTextBuilder.append(afterNodeMark.getMarkText()); String nodeText = nodeTextBuilder.toString(); nodeText = nodeText.replaceAll("@node", Integer.toString(node.getNodeNumber())); nodeText = nodeText.replaceAll("@from", Integer.toString(node.getBackReference())); nodeText = nodeText.replaceAll("@nrow", Integer.toString(numDestinations)); return nodeText; }