OSDN Git Service

AI 143373: am: CL 143223 am: CL 143034 ADT #1738834: Properly validate project name...
authorRaphael Moll <>
Sat, 28 Mar 2009 02:29:45 +0000 (19:29 -0700)
committerThe Android Open Source Project <initial-contribution@android.com>
Sat, 28 Mar 2009 02:29:45 +0000 (19:29 -0700)
  activity name for "create project".
  Also validate AVD name for "create avd".
  Original author: raphael
  Merged from: //branches/cupcake/...
  Original author: android-build
  Merged from: //branches/donutburger/...

Automated import of CL 143373

sdkmanager/app/src/com/android/sdkmanager/Main.java
sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java

index 154788e..adf37ed 100644 (file)
@@ -35,6 +35,7 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 /**
  * Main class for the 'android' application.
@@ -50,6 +51,12 @@ class Main {
     private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
     private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
 
+    /** Regex used to validate characters that compose an AVD name. */
+    private final static Pattern RE_AVD_NAME = Pattern.compile("[a-zA-Z0-9._-]+");
+    /** List of valid characters for an AVD name. Used for display purposes. */
+    private final static String CHARS_AVD_NAME = "a-z A-Z 0-9 . _ -";
+    
+    
     /** Path to the SDK folder. This is the parent of {@link #TOOLSDIR}. */
     private String mSdkFolder;
     /** Logger object. Use this to print normal output, warnings or errors. */
@@ -239,11 +246,41 @@ class Main {
                 mSdkLog);
 
         String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+
+        String projectName = mSdkCommandLine.getParamName();
+        String packageName = mSdkCommandLine.getParamProjectPackage();
+        String activityName = mSdkCommandLine.getParamProjectActivity();
         
+        if (projectName != null &&
+                !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
+            errorAndExit(
+                "Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
+                projectName, ProjectCreator.CHARS_PROJECT_NAME);
+            return;
+        }
+
+        if (activityName != null &&
+                !ProjectCreator.RE_ACTIVITY_NAME.matcher(activityName).matches()) {
+            errorAndExit(
+                "Activity name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
+                activityName, ProjectCreator.CHARS_ACTIVITY_NAME);
+            return;
+        }
+
+        if (packageName != null &&
+                !ProjectCreator.RE_PACKAGE_NAME.matcher(packageName).matches()) {
+            errorAndExit(
+                "Package name '%1$s' contains invalid characters.\n" +
+                "A package name must be constitued of two Java identifiers.\n" +
+                "Each identifier allowed characters are: %2$s",
+                packageName, ProjectCreator.CHARS_PACKAGE_NAME);
+            return;
+        }
+
         creator.createProject(projectDir,
-                mSdkCommandLine.getParamName(),
-                mSdkCommandLine.getParamProjectPackage(),
-                mSdkCommandLine.getParamProjectActivity(),
+                projectName,
+                activityName,
+                packageName,
                 target,
                 false /* isTestProject*/);
     }
@@ -447,6 +484,14 @@ class Main {
             AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
 
             String avdName = mSdkCommandLine.getParamName();
+            
+            if (!RE_AVD_NAME.matcher(avdName).matches()) {
+                errorAndExit(
+                    "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
+                    avdName, CHARS_AVD_NAME);
+                return;
+            }
+            
             AvdInfo info = avdManager.getAvd(avdName);
             if (info != null) {
                 if (mSdkCommandLine.getFlagForce()) {
index 7489b65..b84be18 100644 (file)
@@ -62,6 +62,27 @@ public class ProjectCreator {
     
     private final static String FOLDER_TESTS = "tests";
     
+    /** Pattern for characters accepted in a project name. Since this will be used as a
+     * directory name, we're being a bit conservative on purpose: dot and space cannot be used. */
+    public static final Pattern RE_PROJECT_NAME = Pattern.compile("[a-zA-Z0-9_]+");
+    /** List of valid characters for a project name. Used for display purposes. */
+    public final static String CHARS_PROJECT_NAME = "a-z A-Z 0-9 _";
+
+    /** Pattern for characters accepted in a package name. A package is list of Java identifier
+     * separated by a dot. We need to have at least one dot (e.g. a two-level package name). 
+     * A Java identifier cannot start by a digit. */
+    public static final Pattern RE_PACKAGE_NAME =
+        Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)+");
+    /** List of valid characters for a project name. Used for display purposes. */
+    public final static String CHARS_PACKAGE_NAME = "a-z A-Z 0-9 _";
+
+    /** Pattern for characters accepted in an activity name, which is a Java identifier. */
+    public static final Pattern RE_ACTIVITY_NAME =
+        Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");
+    /** List of valid characters for a project name. Used for display purposes. */
+    public final static String CHARS_ACTIVITY_NAME = "a-z A-Z 0-9 _";
+
+    
     public enum OutputLevel {
         /** Silent mode. Project creation will only display errors. */
         SILENT,
@@ -106,11 +127,17 @@ public class ProjectCreator {
     
     /**
      * Creates a new project.
+     * <p/>
+     * The caller should have already checked and sanitized the parameters.
      * 
      * @param folderPath the folder of the project to create.
-     * @param projectName the name of the project.
-     * @param packageName the package of the project.
-     * @param activityName the activity of the project as it will appear in the manifest.
+     * @param projectName the name of the project. The name must match the
+     *          {@link #RE_PROJECT_NAME} regex.
+     * @param packageName the package of the project. The name must match the
+     *          {@link #RE_PACKAGE_NAME} regex.
+     * @param activityName the activity of the project as it will appear in the manifest. Can be
+     *          null if no activity should be created. The name must match the
+     *          {@link #RE_ACTIVITY_NAME} regex. 
      * @param target the project target.
      * @param isTestProject whether the project to create is a test project.
      */