1 /*******************************************************************************
 
   2  * Copyright (c) 2000, 2003 IBM Corporation and others.
 
   3  * All rights reserved. This program and the accompanying materials 
 
   4  * are made available under the terms of the Common Public License v1.0
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v10.html
 
   9  *     IBM Corporation - initial API and implementation
 
  10  *******************************************************************************/
 
  11 package net.sourceforge.phpeclipse.obfuscator;
 
  13 import java.io.BufferedInputStream;
 
  14 import java.io.BufferedWriter;
 
  16 import java.io.FileNotFoundException;
 
  17 import java.io.FileOutputStream;
 
  18 import java.io.FileWriter;
 
  19 import java.io.IOException;
 
  20 import java.io.InputStream;
 
  21 import java.util.ArrayList;
 
  22 import java.util.HashMap;
 
  24 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 
  25 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 
  26 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 
  27 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
 
  28 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
  29 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
 
  30 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
  31 import net.sourceforge.phpeclipse.ui.WebUI;
 
  33 import org.eclipse.core.resources.IContainer;
 
  34 import org.eclipse.core.resources.IFile;
 
  35 import org.eclipse.core.resources.IResource;
 
  36 import org.eclipse.core.runtime.CoreException;
 
  37 import org.eclipse.core.runtime.IPath;
 
  38 import org.eclipse.jface.preference.IPreferenceStore;
 
  41  * Helper class for exporting resources to the file system.
 
  43 public class ObfuscatorPass2Exporter implements ITerminalSymbols {
 
  44         private Scanner fScanner;
 
  50         protected HashMap fIdentifierMap;
 
  52         public ObfuscatorPass2Exporter(Scanner scanner, HashMap identifierMap) {
 
  54                 fIdentifierMap = identifierMap;
 
  59          * gets the next token from input
 
  61         private void getNextToken() {
 
  64                         fToken = fScanner.getNextToken();
 
  66                                 int currentEndPosition = fScanner.getCurrentTokenEndPosition();
 
  67                                 int currentStartPosition = fScanner
 
  68                                                 .getCurrentTokenStartPosition();
 
  70                                 System.out.print(currentStartPosition + ","
 
  71                                                 + currentEndPosition + ": ");
 
  72                                 System.out.println(fScanner.toStringAction(fToken));
 
  75                 } catch (InvalidInputException e) {
 
  78                 fToken = TokenNameERROR;
 
  81         private boolean obfuscate(StringBuffer buf) {
 
  86                 int startPosition = 0;
 
  89                 IPreferenceStore store = WebUI.getDefault()
 
  90                                 .getPreferenceStore();
 
  92                         while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
 
  93                                 if (fToken == TokenNameVariable) {
 
  94                                         identifier = new String(fScanner
 
  95                                                         .getCurrentIdentifierSource());
 
  96                                         lastPosition = fScanner.startPosition;
 
  97                                         int len = lastPosition - startPosition;
 
  98                                         buf.append(fScanner.source, startPosition, len);
 
  99                                         value = (PHPIdentifier) fIdentifierMap.get(identifier);
 
 101                                                 String obfuscatedIdentifier = value.getIdentifier();
 
 102                                                 if (obfuscatedIdentifier == null) {
 
 103                                                         buf.append("$v" + Integer.toString(fCounter));
 
 104                                                         value.setIdentifier("$v"
 
 105                                                                         + Integer.toString(fCounter++));
 
 107                                                         buf.append(obfuscatedIdentifier);
 
 109                                                 // System.out.println(hexString.toString());
 
 111                                                 buf.append(identifier);
 
 113                                         startPosition = fScanner.currentPosition;
 
 115                                 } else if (fToken == TokenNameIdentifier) {
 
 116                                         identifier = new String(fScanner
 
 117                                                         .getCurrentIdentifierSource());
 
 118                                         lastPosition = fScanner.startPosition;
 
 119                                         int len = lastPosition - startPosition;
 
 120                                         buf.append(fScanner.source, startPosition, len);
 
 121                                         value = (PHPIdentifier) fIdentifierMap.get(identifier);
 
 123                                                 String obfuscatedIdentifier = value.getIdentifier();
 
 124                                                 if (obfuscatedIdentifier == null) {
 
 125                                                         buf.append("_" + Integer.toString(fCounter));
 
 126                                                         value.setIdentifier("_"
 
 127                                                                         + Integer.toString(fCounter++));
 
 129                                                         buf.append(obfuscatedIdentifier);
 
 131                                                 // System.out.println(hexString.toString());
 
 133                                                 buf.append(identifier);
 
 135                                         startPosition = fScanner.currentPosition;
 
 138                                 } else if (fToken == TokenNameCOMMENT_LINE
 
 139                                                 || fToken == TokenNameCOMMENT_BLOCK
 
 140                                                 || fToken == TokenNameCOMMENT_PHPDOC) {
 
 141                                         lastPosition = fScanner.startPosition;
 
 142                                         buf.append(fScanner.source, startPosition, lastPosition
 
 144                                         startPosition = fScanner.currentPosition;
 
 146                                 } else if (fToken == TokenNameStringDoubleQuote) {
 
 147                                         char currentCharacter;
 
 148                                         int i = fScanner.startPosition;
 
 149                                         ArrayList varList = new ArrayList();
 
 151                                         lastPosition = fScanner.startPosition;
 
 152                                         int len = lastPosition - startPosition;
 
 153                                         buf.append(fScanner.source, startPosition, len);
 
 155                                         while (i < fScanner.currentPosition) {
 
 156                                                 currentCharacter = fScanner.source[i++];
 
 157                                                 if (currentCharacter == '$'
 
 158                                                                 && fScanner.source[i - 2] != '\\') {
 
 159                                                         StringBuffer varName = new StringBuffer();
 
 161                                                         while (i < fScanner.currentPosition) {
 
 162                                                                 currentCharacter = fScanner.source[i++];
 
 164                                                                                 .isPHPIdentifierPart(currentCharacter)) {
 
 167                                                                 varName.append(currentCharacter);
 
 169                                                         varList.add(varName.toString());
 
 172                                         StringBuffer stringLiteral = new StringBuffer();
 
 173                                         stringLiteral.append(fScanner.source,
 
 174                                                         fScanner.startPosition, fScanner.currentPosition
 
 175                                                                         - fScanner.startPosition);
 
 180                                         for (int j = 0; j < varList.size(); j++) {
 
 181                                                 stringIdent = (String) varList.get(j);
 
 182                                                 len = stringIdent.length();
 
 183                                                 value = (PHPIdentifier) fIdentifierMap.get(stringIdent);
 
 185                                                         String obfuscatedIdentifier = value.getIdentifier();
 
 186                                                         if (obfuscatedIdentifier == null) {
 
 187                                                                 replacement = "$v" + Integer.toString(fCounter);
 
 188                                                                 value.setIdentifier("$v"
 
 189                                                                                 + Integer.toString(fCounter++));
 
 191                                                                 replacement = obfuscatedIdentifier;
 
 193                                                         // System.out.println(hexString.toString());
 
 195                                                         replacement = stringIdent;
 
 197                                                 index = stringLiteral.indexOf(stringIdent);
 
 200                                                                         && stringLiteral.charAt(index - 1) != '\\') {
 
 201                                                                 stringLiteral.replace(index, index
 
 202                                                                                 + stringIdent.length(), replacement);
 
 203                                                         } else if (index == 0) {
 
 204                                                                 stringLiteral.replace(index, index
 
 205                                                                                 + stringIdent.length(), replacement);
 
 209                                         buf.append(stringLiteral);
 
 210                                         startPosition = fScanner.currentPosition;
 
 213                                 if (fToken == TokenNameMINUS_GREATER) { // i.e. $this->var_name
 
 215                                         if (fToken == TokenNameIdentifier) {
 
 216                                                 // assuming this is a dereferenced variable
 
 217                                                 identifier = new String(fScanner
 
 218                                                                 .getCurrentIdentifierSource());
 
 219                                                 lastPosition = fScanner.startPosition;
 
 220                                                 int len = lastPosition - startPosition;
 
 221                                                 buf.append(fScanner.source, startPosition, len);
 
 222                                                 value = (PHPIdentifier) fIdentifierMap.get("$"
 
 224                                                 if (value != null && value.isVariable()) {
 
 225                                                         String obfuscatedIdentifier = value.getIdentifier();
 
 226                                                         if (obfuscatedIdentifier == null) {
 
 227                                                                 // note: don't place a $ before the identifier
 
 228                                                                 buf.append("v" + Integer.toString(fCounter));
 
 229                                                                 value.setIdentifier("$v"
 
 230                                                                                 + Integer.toString(fCounter++));
 
 232                                                                 if (obfuscatedIdentifier.charAt(0) == '$') {
 
 233                                                                         buf.append(obfuscatedIdentifier
 
 236                                                                         buf.append(obfuscatedIdentifier);
 
 240                                                         buf.append(identifier);
 
 242                                                 startPosition = fScanner.currentPosition;
 
 250                         if (startPosition < fScanner.source.length) {
 
 251                                 buf.append(fScanner.source, startPosition,
 
 252                                                 fScanner.source.length - startPosition);
 
 255                 } catch (SyntaxError sytaxErr) {
 
 263          * Creates the specified file system directory at
 
 264          * <code>destinationPath</code>. This creates a new file system
 
 267         public void createFolder(IPath destinationPath) {
 
 268                 new File(destinationPath.toOSString()).mkdir();
 
 272          * Writes the passed resource to the specified location recursively
 
 274         public void write(IResource resource, IPath destinationPath)
 
 275                         throws CoreException, IOException {
 
 276                 if (resource.getType() == IResource.FILE)
 
 277                         writeFile((IFile) resource, destinationPath);
 
 279                         writeChildren((IContainer) resource, destinationPath);
 
 283          * Exports the passed container's children
 
 285         protected void writeChildren(IContainer folder, IPath destinationPath)
 
 286                         throws CoreException, IOException {
 
 287                 if (folder.isAccessible()) {
 
 288                         IResource[] children = folder.members();
 
 289                         for (int i = 0; i < children.length; i++) {
 
 290                                 IResource child = children[i];
 
 291                                 writeResource(child, destinationPath.append(child.getName()));
 
 297          * Writes the passed file resource to the specified destination on the local
 
 300         protected void writeFile(IFile file, IPath destinationPath)
 
 301                         throws IOException, CoreException {
 
 302                 if (PHPFileUtil.isPHPFile(file)) {
 
 303                         InputStream stream = null;
 
 304                         char[] charArray = null;
 
 306                                 stream = new BufferedInputStream(file.getContents());
 
 307                                 charArray = Util.getInputStreamAsCharArray(stream, -1, null);
 
 308                         } catch (IOException e) {
 
 312                                         if (stream != null) {
 
 315                                 } catch (IOException e) {
 
 319                         if (charArray == null) {
 
 320                                 // TODO show error message
 
 324                         fScanner.setSource(charArray);
 
 325                         fScanner.setPHPMode(false);
 
 326                         fToken = TokenNameEOF;
 
 329                         StringBuffer buf = new StringBuffer();
 
 330                         if (!obfuscate(buf)) {
 
 331                                 copyFile(file, destinationPath);
 
 333                                 // charArray = buf.toString().toCharArray();
 
 334                                 // File targetFile = new File(destinationPath.toOSString());
 
 335                                 BufferedWriter bw = new BufferedWriter(new FileWriter(
 
 336                                                 destinationPath.toOSString()));
 
 337                                 bw.write(buf.toString());
 
 342                         copyFile(file, destinationPath);
 
 346         private void copyFile(IFile file, IPath destinationPath)
 
 347                         throws FileNotFoundException, CoreException, IOException {
 
 348                 FileOutputStream output = null;
 
 349                 InputStream contentStream = null;
 
 352                         output = new FileOutputStream(destinationPath.toOSString());
 
 353                         contentStream = file.getContents(false);
 
 354                         int chunkSize = contentStream.available();
 
 355                         byte[] readBuffer = new byte[chunkSize];
 
 356                         int n = contentStream.read(readBuffer);
 
 359                                 output.write(readBuffer);
 
 360                                 n = contentStream.read(readBuffer);
 
 365                         if (contentStream != null)
 
 366                                 contentStream.close();
 
 371          * Writes the passed resource to the specified location recursively
 
 373         protected void writeResource(IResource resource, IPath destinationPath)
 
 374                         throws CoreException, IOException {
 
 375                 if (resource.getType() == IResource.FILE)
 
 376                         writeFile((IFile) resource, destinationPath);
 
 378                         createFolder(destinationPath);
 
 379                         writeChildren((IContainer) resource, destinationPath);