Program: 25075
Project: 25075
Buggy source:
/** 
 * <p>Get all uploads specified in the DALI parameter "UPLOAD" from the given request parameters.</p> <p><i>Note: This function is case INsensitive for the "UPLOAD" parameter. </i></p> <p><b>WARNING:</b> Calling this function modifies the given map ONLY IF the "UPLOAD" parameter (whatever is its case) is found. In such case, the following modifications are applied: </p> <ul> <li> All "UPLOAD" parameters will be removed and then added again in the map with their corresponding   {@link DALIUpload} item (not any more a String).</li> <li> If <i>allowTAPSyntax</i> is <i>true</i>, several uploads may be specified in the same "UPLOAD" parameter value. For more clarity for the user (once the parameters listed), this list of uploads will be split in the same number of "UPLOAD" parameters. That's to say, there will be only one "UPLOAD" item in the Map, but its value will be an array containing every specified uploads: <i>an array of  {@link DALIUpload} objects</i>.</li> <li> If there is at least one "UPLOAD" parameter, all uploaded files (parameters associated with instances of  {@link UploadFile}) will be removed from the map (and also from the file system). They are indeed not useful for a DALI service since all interesting uploads have already been listed. </li> </ul> <p><i>Note: This function can be called several times on the same map. After a first call, this function will just gathers into a List all found   {@link DALIUpload} objects. Of course, only uploads specified in the "UPLOAD" parameter(s) will be returned and others will be removedas explained above. </i></p> <h3>DALI and TAP syntax</h3> <p> The "UPLOAD" parameter lists all files to consider as uploaded. The syntax for one item is the following: "{name},{uri}", where {uri} is "param:{param-ref}" when the file is provided inline in the parameter named {param-ref}, otherwise, it can be any valid URI (http:..., ftp:..., vos:..., ivo:..., etc...). </p> <p> The parameter <i>allowTAPSyntax</i> lets switch between the DALI and TAP syntax. The only difference between them, is in the way to list multiple uploads. In TAP, they can be given as a semicolon separated list in a single parameter, whereas in DALI, there must be submitted as several individual parameters. For instance: </p> <ul> <li><b>In TAP:</b> "UPLOAD=tableA,param:foo;tableB,http://..." =&gt; only 1 parameter</li> <li><b>In DALI:</b> "UPLOAD=tableA,param:foo" and "UPLOAD=tableB,http://..." =&gt; 2 parameters</li> </ul> <p><i>Note: Because of the possible presence of a semicolon in a URI (which is also used as separator of uploads in the TAP syntax), there could be a problem while splitting the uploads specified in "UPLOAD". In that case, it is strongly recommended to either encode the URI (in UTF-8) (i.e. ";" becomes "%3B") or to merely restrict the syntax to the DALI one. In this last case, the parameter  {@link #allowTAPSyntax} should be set to <i>false</i> and then all parameters should be submitted individually.</i></p>
 * @param requestParams		All parameters extracted from an HTTP request by a {@link RequestParser}.
 * @param allowTAPSyntax	<i>true</i> to allow a list of several upload items in one "UPLOAD" parameter value (each item separated by a semicolon),<i>false</i> to forbid it (and so, multiple upload items shall be submitted individually).
 * @param fileManager		The file manager to use in order to build a {@link DALIUpload} objects from a URI.<i>(a link to the file manager will be set in the  {@link DALIUpload} object in order to open itwhenever it will asked after its creation)</i>
 * @return	List of all uploads specified with the DALI or TAP syntax.
 * @throws TAPException	If the syntax of an "UPLOAD" parameter is wrong.
 * @see {@link RequestParser#parse(javax.servlet.http.HttpServletRequest)}
 */
public final static List<DALIUpload> getDALIUploads(final Map<String,Object> requestParams,final boolean allowTAPSyntax,final UWSFileManager fileManager) throws TAPException {
  ArrayList<DALIUpload> uploads=new ArrayList<DALIUpload>(3);
  ArrayList<String> usedFiles=new ArrayList<String>(3);
  Iterator<Map.Entry<String,Object>> it=requestParams.entrySet().iterator();
  Map.Entry<String,Object> entry;
  Object value;
  while (it.hasNext()) {
    entry=it.next();
    if (entry.getKey() != null && entry.getKey().toLowerCase().equals(TAPJob.PARAM_UPLOAD)) {
      value=entry.getValue();
      if (value != null) {
        if (value instanceof DALIUpload) {
          DALIUpload upl=(DALIUpload)value;
          uploads.add(upl);
          if (!upl.isByReference())           usedFiles.add(upl.file.paramName);
        }
 else         if (value instanceof String)         fetchDALIUploads(uploads,usedFiles,(String)value,requestParams,allowTAPSyntax,fileManager);
 else         if (value.getClass().isArray()) {
          Object[] objects=(Object[])value;
          for (          Object o : objects) {
            if (o != null) {
              if (o instanceof DALIUpload)               uploads.add((DALIUpload)o);
 else               if (o instanceof String)               fetchDALIUploads(uploads,usedFiles,(String)o,requestParams,allowTAPSyntax,fileManager);
            }
          }
        }
      }
      it.remove();
    }
  }
  if (uploads.size() > 0) {
    it=requestParams.entrySet().iterator();
    while (it.hasNext()) {
      entry=it.next();
      value=entry.getValue();
      if (value == null)       it.remove();
 else       if (value instanceof UploadFile && !usedFiles.contains(entry.getKey())) {
        try {
          ((UploadFile)value).deleteFile();
        }
 catch (        IOException ioe) {
        }
        it.remove();
      }
 else       if (value.getClass().isArray()) {
        Object[] objects=(Object[])value;
        int cnt=objects.length;
        for (int i=0; i < objects.length; i++) {
          if (objects[i] == null) {
            objects[i]=null;
            cnt--;
          }
 else           if (objects[i] instanceof UploadFile && !usedFiles.contains(entry.getKey())) {
            try {
              ((UploadFile)objects[i]).deleteFile();
            }
 catch (            IOException ioe) {
            }
            objects[i]=null;
            cnt--;
          }
        }
        if (cnt == 0)         it.remove();
      }
    }
  }
  requestParams.put("String_Node_Str",uploads.toArray(new DALIUpload[uploads.size()]));
  return uploads;
}

Fixed version (ground truth):
/** 
 * <p>Get all uploads specified in the DALI parameter "UPLOAD" from the given request parameters.</p> <p><i>Note: This function is case INsensitive for the "UPLOAD" parameter. </i></p> <p><b>WARNING:</b> Calling this function modifies the given map ONLY IF the "UPLOAD" parameter (whatever is its case) is found. In such case, the following modifications are applied: </p> <ul> <li> All "UPLOAD" parameters will be removed and then added again in the map with their corresponding   {@link DALIUpload} item (not any more a String).</li> <li> If <i>allowTAPSyntax</i> is <i>true</i>, several uploads may be specified in the same "UPLOAD" parameter value. For more clarity for the user (once the parameters listed), this list of uploads will be split in the same number of "UPLOAD" parameters. That's to say, there will be only one "UPLOAD" item in the Map, but its value will be an array containing every specified uploads: <i>an array of  {@link DALIUpload} objects</i>.</li> <li> If there is at least one "UPLOAD" parameter, all uploaded files (parameters associated with instances of  {@link UploadFile}) will be removed from the map (and also from the file system). They are indeed not useful for a DALI service since all interesting uploads have already been listed. </li> </ul> <p><i>Note: This function can be called several times on the same map. After a first call, this function will just gathers into a List all found   {@link DALIUpload} objects. Of course, only uploads specified in the "UPLOAD" parameter(s) will be returned and others will be removedas explained above. </i></p> <h3>DALI and TAP syntax</h3> <p> The "UPLOAD" parameter lists all files to consider as uploaded. The syntax for one item is the following: "{name},{uri}", where {uri} is "param:{param-ref}" when the file is provided inline in the parameter named {param-ref}, otherwise, it can be any valid URI (http:..., ftp:..., vos:..., ivo:..., etc...). </p> <p> The parameter <i>allowTAPSyntax</i> lets switch between the DALI and TAP syntax. The only difference between them, is in the way to list multiple uploads. In TAP, they can be given as a semicolon separated list in a single parameter, whereas in DALI, there must be submitted as several individual parameters. For instance: </p> <ul> <li><b>In TAP:</b> "UPLOAD=tableA,param:foo;tableB,http://..." =&gt; only 1 parameter</li> <li><b>In DALI:</b> "UPLOAD=tableA,param:foo" and "UPLOAD=tableB,http://..." =&gt; 2 parameters</li> </ul> <p><i>Note: Because of the possible presence of a semicolon in a URI (which is also used as separator of uploads in the TAP syntax), there could be a problem while splitting the uploads specified in "UPLOAD". In that case, it is strongly recommended to either encode the URI (in UTF-8) (i.e. ";" becomes "%3B") or to merely restrict the syntax to the DALI one. In this last case, the parameter  {@link #allowTAPSyntax} should be set to <i>false</i> and then all parameters should be submitted individually.</i></p>
 * @param requestParams		All parameters extracted from an HTTP request by a {@link RequestParser}.
 * @param allowTAPSyntax	<i>true</i> to allow a list of several upload items in one "UPLOAD" parameter value (each item separated by a semicolon),<i>false</i> to forbid it (and so, multiple upload items shall be submitted individually).
 * @param fileManager		The file manager to use in order to build a {@link DALIUpload} objects from a URI.<i>(a link to the file manager will be set in the  {@link DALIUpload} object in order to open itwhenever it will asked after its creation)</i>
 * @return	List of all uploads specified with the DALI or TAP syntax.
 * @throws TAPException	If the syntax of an "UPLOAD" parameter is wrong.
 * @see {@link RequestParser#parse(javax.servlet.http.HttpServletRequest)}
 */
public final static List<DALIUpload> getDALIUploads(final Map<String,Object> requestParams,final boolean allowTAPSyntax,final UWSFileManager fileManager) throws TAPException {
  ArrayList<DALIUpload> uploads=new ArrayList<DALIUpload>(3);
  ArrayList<String> usedFiles=new ArrayList<String>(3);
  Iterator<Map.Entry<String,Object>> it=requestParams.entrySet().iterator();
  Map.Entry<String,Object> entry;
  Object value;
  while (it.hasNext()) {
    entry=it.next();
    if (entry.getKey() != null && entry.getKey().toLowerCase().equals(TAPJob.PARAM_UPLOAD)) {
      value=entry.getValue();
      if (value != null) {
        if (value instanceof DALIUpload) {
          DALIUpload upl=(DALIUpload)value;
          uploads.add(upl);
          if (!upl.isByReference())           usedFiles.add(upl.file.paramName);
        }
 else         if (value instanceof String)         fetchDALIUploads(uploads,usedFiles,(String)value,requestParams,allowTAPSyntax,fileManager);
 else         if (value.getClass().isArray()) {
          Object[] objects=(Object[])value;
          for (          Object o : objects) {
            if (o != null) {
              if (o instanceof DALIUpload)               uploads.add((DALIUpload)o);
 else               if (o instanceof String)               fetchDALIUploads(uploads,usedFiles,(String)o,requestParams,allowTAPSyntax,fileManager);
            }
          }
        }
      }
      it.remove();
    }
  }
  if (uploads.size() > 0) {
    it=requestParams.entrySet().iterator();
    while (it.hasNext()) {
      entry=it.next();
      value=entry.getValue();
      if (value == null)       it.remove();
 else       if (value instanceof UploadFile && !usedFiles.contains(entry.getKey())) {
        try {
          ((UploadFile)value).deleteFile();
        }
 catch (        IOException ioe) {
        }
        it.remove();
      }
 else       if (value.getClass().isArray()) {
        Object[] objects=(Object[])value;
        int cnt=objects.length;
        for (int i=0; i < objects.length; i++) {
          if (objects[i] == null) {
            objects[i]=null;
            cnt--;
          }
 else           if (objects[i] instanceof UploadFile && !usedFiles.contains(entry.getKey())) {
            try {
              ((UploadFile)objects[i]).deleteFile();
            }
 catch (            IOException ioe) {
            }
            objects[i]=null;
            cnt--;
          }
        }
        if (cnt == 0)         it.remove();
      }
    }
  }
  if (uploads.size() > 0)   requestParams.put("String_Node_Str",uploads.toArray(new DALIUpload[uploads.size()]));
  return uploads;
}