X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass2Exporter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass2Exporter.java new file mode 100644 index 0000000..7898633 --- /dev/null +++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass2Exporter.java @@ -0,0 +1,382 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.obfuscator; + +import java.io.BufferedInputStream; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; + +import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; +import net.sourceforge.phpdt.core.compiler.InvalidInputException; +import net.sourceforge.phpdt.internal.compiler.parser.Scanner; +import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.ui.WebUI; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.preference.IPreferenceStore; + +/** + * Helper class for exporting resources to the file system. + */ +public class ObfuscatorPass2Exporter implements ITerminalSymbols { + private Scanner fScanner; + + private int fToken; + + private int fCounter; + + protected HashMap fIdentifierMap; + + public ObfuscatorPass2Exporter(Scanner scanner, HashMap identifierMap) { + fScanner = scanner; + fIdentifierMap = identifierMap; + fCounter = 0; + } + + /** + * gets the next token from input + */ + private void getNextToken() { + + try { + fToken = fScanner.getNextToken(); + if (Scanner.DEBUG) { + int currentEndPosition = fScanner.getCurrentTokenEndPosition(); + int currentStartPosition = fScanner + .getCurrentTokenStartPosition(); + + System.out.print(currentStartPosition + "," + + currentEndPosition + ": "); + System.out.println(fScanner.toStringAction(fToken)); + } + return; + } catch (InvalidInputException e) { + + } + fToken = TokenNameERROR; + } + + private boolean obfuscate(StringBuffer buf) { + char[] ident; + String identifier; + PHPIdentifier value; + + int startPosition = 0; + int lastPosition = 0; + + IPreferenceStore store = WebUI.getDefault() + .getPreferenceStore(); + try { + while (fToken != TokenNameEOF && fToken != TokenNameERROR) { + if (fToken == TokenNameVariable) { + identifier = new String(fScanner + .getCurrentIdentifierSource()); + lastPosition = fScanner.startPosition; + int len = lastPosition - startPosition; + buf.append(fScanner.source, startPosition, len); + value = (PHPIdentifier) fIdentifierMap.get(identifier); + if (value != null) { + String obfuscatedIdentifier = value.getIdentifier(); + if (obfuscatedIdentifier == null) { + buf.append("$v" + Integer.toString(fCounter)); + value.setIdentifier("$v" + + Integer.toString(fCounter++)); + } else { + buf.append(obfuscatedIdentifier); + } + // System.out.println(hexString.toString()); + } else { + buf.append(identifier); + } + startPosition = fScanner.currentPosition; + getNextToken(); + } else if (fToken == TokenNameIdentifier) { + identifier = new String(fScanner + .getCurrentIdentifierSource()); + lastPosition = fScanner.startPosition; + int len = lastPosition - startPosition; + buf.append(fScanner.source, startPosition, len); + value = (PHPIdentifier) fIdentifierMap.get(identifier); + if (value != null) { + String obfuscatedIdentifier = value.getIdentifier(); + if (obfuscatedIdentifier == null) { + buf.append("_" + Integer.toString(fCounter)); + value.setIdentifier("_" + + Integer.toString(fCounter++)); + } else { + buf.append(obfuscatedIdentifier); + } + // System.out.println(hexString.toString()); + } else { + buf.append(identifier); + } + startPosition = fScanner.currentPosition; + getNextToken(); + + } else if (fToken == TokenNameCOMMENT_LINE + || fToken == TokenNameCOMMENT_BLOCK + || fToken == TokenNameCOMMENT_PHPDOC) { + lastPosition = fScanner.startPosition; + buf.append(fScanner.source, startPosition, lastPosition + - startPosition); + startPosition = fScanner.currentPosition; + getNextToken(); + } else if (fToken == TokenNameStringDoubleQuote) { + char currentCharacter; + int i = fScanner.startPosition; + ArrayList varList = new ArrayList(); + + lastPosition = fScanner.startPosition; + int len = lastPosition - startPosition; + buf.append(fScanner.source, startPosition, len); + + while (i < fScanner.currentPosition) { + currentCharacter = fScanner.source[i++]; + if (currentCharacter == '$' + && fScanner.source[i - 2] != '\\') { + StringBuffer varName = new StringBuffer(); + varName.append("$"); + while (i < fScanner.currentPosition) { + currentCharacter = fScanner.source[i++]; + if (!Scanner + .isPHPIdentifierPart(currentCharacter)) { + break; // while loop + } + varName.append(currentCharacter); + } + varList.add(varName.toString()); + } + } + StringBuffer stringLiteral = new StringBuffer(); + stringLiteral.append(fScanner.source, + fScanner.startPosition, fScanner.currentPosition + - fScanner.startPosition); + String stringIdent; + String replacement; + int index; + + for (int j = 0; j < varList.size(); j++) { + stringIdent = (String) varList.get(j); + len = stringIdent.length(); + value = (PHPIdentifier) fIdentifierMap.get(stringIdent); + if (value != null) { + String obfuscatedIdentifier = value.getIdentifier(); + if (obfuscatedIdentifier == null) { + replacement = "$v" + Integer.toString(fCounter); + value.setIdentifier("$v" + + Integer.toString(fCounter++)); + } else { + replacement = obfuscatedIdentifier; + } + // System.out.println(hexString.toString()); + } else { + replacement = stringIdent; + } + index = stringLiteral.indexOf(stringIdent); + if (index >= 0) { + if (index > 0 + && stringLiteral.charAt(index - 1) != '\\') { + stringLiteral.replace(index, index + + stringIdent.length(), replacement); + } else if (index == 0) { + stringLiteral.replace(index, index + + stringIdent.length(), replacement); + } + } + } + buf.append(stringLiteral); + startPosition = fScanner.currentPosition; + getNextToken(); + } + if (fToken == TokenNameMINUS_GREATER) { // i.e. $this->var_name + getNextToken(); + if (fToken == TokenNameIdentifier) { + // assuming this is a dereferenced variable + identifier = new String(fScanner + .getCurrentIdentifierSource()); + lastPosition = fScanner.startPosition; + int len = lastPosition - startPosition; + buf.append(fScanner.source, startPosition, len); + value = (PHPIdentifier) fIdentifierMap.get("$" + + identifier); + if (value != null && value.isVariable()) { + String obfuscatedIdentifier = value.getIdentifier(); + if (obfuscatedIdentifier == null) { + // note: don't place a $ before the identifier + buf.append("v" + Integer.toString(fCounter)); + value.setIdentifier("$v" + + Integer.toString(fCounter++)); + } else { + if (obfuscatedIdentifier.charAt(0) == '$') { + buf.append(obfuscatedIdentifier + .substring(1)); + } else { + buf.append(obfuscatedIdentifier); + } + } + } else { + buf.append(identifier); + } + startPosition = fScanner.currentPosition; + getNextToken(); + } + + } else { + getNextToken(); + } + } + if (startPosition < fScanner.source.length) { + buf.append(fScanner.source, startPosition, + fScanner.source.length - startPosition); + } + return true; + } catch (SyntaxError sytaxErr) { + // do nothing + } + + return false; + } + + /** + * Creates the specified file system directory at + * destinationPath. This creates a new file system + * directory. + */ + public void createFolder(IPath destinationPath) { + new File(destinationPath.toOSString()).mkdir(); + } + + /** + * Writes the passed resource to the specified location recursively + */ + public void write(IResource resource, IPath destinationPath) + throws CoreException, IOException { + if (resource.getType() == IResource.FILE) + writeFile((IFile) resource, destinationPath); + else + writeChildren((IContainer) resource, destinationPath); + } + + /** + * Exports the passed container's children + */ + protected void writeChildren(IContainer folder, IPath destinationPath) + throws CoreException, IOException { + if (folder.isAccessible()) { + IResource[] children = folder.members(); + for (int i = 0; i < children.length; i++) { + IResource child = children[i]; + writeResource(child, destinationPath.append(child.getName())); + } + } + } + + /** + * Writes the passed file resource to the specified destination on the local + * file system + */ + protected void writeFile(IFile file, IPath destinationPath) + throws IOException, CoreException { + if (PHPFileUtil.isPHPFile(file)) { + InputStream stream = null; + char[] charArray = null; + try { + stream = new BufferedInputStream(file.getContents()); + charArray = Util.getInputStreamAsCharArray(stream, -1, null); + } catch (IOException e) { + return; + } finally { + try { + if (stream != null) { + stream.close(); + } + } catch (IOException e) { + } + } + + if (charArray == null) { + // TODO show error message + return; + } + + fScanner.setSource(charArray); + fScanner.setPHPMode(false); + fToken = TokenNameEOF; + getNextToken(); + + StringBuffer buf = new StringBuffer(); + if (!obfuscate(buf)) { + copyFile(file, destinationPath); + } else { + // charArray = buf.toString().toCharArray(); + // File targetFile = new File(destinationPath.toOSString()); + BufferedWriter bw = new BufferedWriter(new FileWriter( + destinationPath.toOSString())); + bw.write(buf.toString()); + bw.close(); + } + + } else { + copyFile(file, destinationPath); + } + } + + private void copyFile(IFile file, IPath destinationPath) + throws FileNotFoundException, CoreException, IOException { + FileOutputStream output = null; + InputStream contentStream = null; + + try { + output = new FileOutputStream(destinationPath.toOSString()); + contentStream = file.getContents(false); + int chunkSize = contentStream.available(); + byte[] readBuffer = new byte[chunkSize]; + int n = contentStream.read(readBuffer); + + while (n > 0) { + output.write(readBuffer); + n = contentStream.read(readBuffer); + } + } finally { + if (output != null) + output.close(); + if (contentStream != null) + contentStream.close(); + } + } + + /** + * Writes the passed resource to the specified location recursively + */ + protected void writeResource(IResource resource, IPath destinationPath) + throws CoreException, IOException { + if (resource.getType() == IResource.FILE) + writeFile((IFile) resource, destinationPath); + else { + createFolder(destinationPath); + writeChildren((IContainer) resource, destinationPath); + } + } +}