--- /dev/null
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.juplo</groupId>
+ <artifactId>fix-swf</artifactId>
+ <packaging>war</packaging>
+ <version>1.0</version>
+ <name>fix-swf</name>
+ <url>http://juplo.de/fix-swf</url>
+ <properties>
+ <commons-fileupload.version>1.2.2</commons-fileupload.version>
+ <commons-lang.version>2.6</commons-lang.version>
+ <servlet-api.version>2.5</servlet-api.version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ <version>${commons-fileupload.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>${commons-lang.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>${servlet-api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>fix-swf</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ <encoding>utf8</encoding>
+ <showWarnings>true</showWarnings>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>tomcat-maven-plugin</artifactId>
+ <version>1.1</version>
+ <configuration>
+ <path>/</path>
+ <uriEncoding>UTF-8</uriEncoding>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package de.juplo.fixswf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.fileupload.FileItemIterator;
+import org.apache.commons.fileupload.FileItemStream;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.lang.StringEscapeUtils;
+
+/**
+ *
+ * @author kai
+ */
+public class FixSwfServlet extends HttpServlet
+{
+ public final String MESSAGE_ATTRIBUTE = getClass().getCanonicalName() + ".MESSAGE";
+
+ private Map<Byte,Byte> corrections;
+ private Pattern pattern;
+
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ corrections = new HashMap<Byte,Byte>();
+ corrections.put((byte)12, (byte)10);
+ corrections.put((byte)14, (byte)11);
+ pattern = Pattern.compile("([^/\\\\:<>?\"]+?)(?:\\.swf)?$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
+ }
+
+
+ /**
+ * Processes requests for both HTTP
+ * <code>GET</code> and
+ * <code>POST</code> methods.
+ *
+ * @param request servlet request
+ * @param response servlet response
+ * @throws ServletException if a servlet-specific error occurs
+ * @throws IOException if an I/O error occurs
+ */
+ protected void processRequest(
+ HttpServletRequest request,
+ HttpServletResponse response
+ )
+ throws
+ ServletException,
+ IOException
+ {
+ response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
+ }
+
+ /**
+ * Handles the HTTP
+ * <code>GET</code> method.
+ *
+ * @param request servlet request
+ * @param response servlet response
+ * @throws ServletException if a servlet-specific error occurs
+ * @throws IOException if an I/O error occurs
+ */
+ @Override
+ protected void doGet(
+ HttpServletRequest request,
+ HttpServletResponse response
+ )
+ throws
+ ServletException,
+ IOException
+ {
+ response.setContentType("text/html;charset=UTF-8");
+ PrintWriter out = response.getWriter();
+ try
+ {
+ out.println("<html>");
+ out.println("<head>");
+ out.println("<title>Fix-Swf</title>");
+ out.println("</head>");
+ out.println("<body>");
+ if (request.getAttribute(MESSAGE_ATTRIBUTE) != null)
+ {
+ out.println("<h1>Upload-Results</h1>");
+ out.println("<p>" + StringEscapeUtils.escapeHtml((String)request.getAttribute(MESSAGE_ATTRIBUTE)) + "</p>");
+ }
+ out.println("<h1>Choose SWF-File to check/fix</h1>");
+ out.println("<p>If the file has to be fixed, the fixed version will be presented to you as a download.</p>");
+ out.println("<form action=\"\" method=\"post\" enctype=\"multipart/form-data\">");
+ out.println("<input type=\"file\" name=\"swf\" />");
+ out.println("<input type=\"submit\" name=\"submit\" value=\"Start Upload\" />");
+ out.println("</form>");
+ out.println("</body>");
+ out.println("</html>");
+ }
+ finally
+ {
+ out.close();
+ }
+ }
+
+ /**
+ * Handles the HTTP
+ * <code>POST</code> method.
+ *
+ * @param request servlet request
+ * @param response servlet response
+ * @throws ServletException if a servlet-specific error occurs
+ * @throws IOException if an I/O error occurs
+ */
+ @Override
+ protected void doPost(
+ HttpServletRequest request,
+ HttpServletResponse response
+ )
+ throws
+ ServletException,
+ IOException
+ {
+ // Check that we have a file upload request
+ if (!ServletFileUpload.isMultipartContent(request))
+ {
+ request.setAttribute(MESSAGE_ATTRIBUTE, "No data uploaded!");
+ request.getRequestDispatcher("/").forward(request, response);
+ return;
+ }
+
+ // Create a new file upload handler
+ ServletFileUpload upload = new ServletFileUpload();
+
+ try
+ {
+ // Parse the request
+ FileItemIterator iter = upload.getItemIterator(request);
+
+ while(iter.hasNext())
+ {
+ FileItemStream item = iter.next();
+
+ if (item.isFormField())
+ continue;
+
+ if (!item.getFieldName().equals("swf"))
+ continue;
+
+ String filename = item.getName();
+ InputStream in = item.openStream();
+ byte[] buffer = new byte[512];
+ int i;
+ i = in.read(buffer);
+
+ if (i < 4)
+ {
+ request.setAttribute(MESSAGE_ATTRIBUTE, "Not enough data uploaded!");
+ request.getRequestDispatcher("/").forward(request, response);
+ return;
+ }
+
+ if (!corrections.containsKey(buffer[3]))
+ {
+ request.setAttribute(MESSAGE_ATTRIBUTE, "Uploaded SWF-file " + filename + " was valid!");
+ request.getRequestDispatcher("/").forward(request, response);
+ return;
+ }
+
+ /** Correct the Flash-Player-Version in Header-Byte 4 */
+ buffer[3] = corrections.get(buffer[3]);
+
+ Matcher matcher = pattern.matcher(filename);
+ if (matcher.matches())
+ {
+ filename = matcher.group(1) + "_FIXED.swf";
+ }
+ else
+ {
+ filename = "FIXED.swf";
+ }
+
+ response.setHeader("Content-Type", "application/x-shockwave-flash");
+ response.setHeader("Content-Disposition","attachment; filename=\"" + filename + "\"");
+ OutputStream out = response.getOutputStream();
+ do
+ {
+ out.write(buffer, 0, i);
+ }
+ while ((i = in.read(buffer)) > -1);
+
+ out.close();
+ }
+ }
+ catch (Exception e)
+ {
+ request.setAttribute(MESSAGE_ATTRIBUTE, "Error while parsing upload: " + e);
+ request.getRequestDispatcher("/").forward(request, response);
+ return;
+ }
+
+ /** Fallback, if no data was found (happens when forwarding!) */
+ doGet(request, response);
+ }
+
+ /**
+ * Returns a short description of the servlet.
+ *
+ * @return a String containing servlet description
+ */
+ @Override
+ public String getServletInfo() {
+ return "This Servlet fixes the 4th byte of an uploaded SWF-file according to the SWF-filestructre specification.";
+ }
+}