Skip to content

Commit f0c0099

Browse files
NmurtasDevclaude
andcommitted
Add AVD name validation to prevent spaces and special characters
- Add isValidAvdName() method to validate AVD names - Enforce pattern: letters, numbers, underscores, and hyphens only (^[a-zA-Z0-9_-]+$) - Block spaces and special characters that could cause issues - Validate on AVD creation (createAvdDialog) - Validate on AVD rename (renameAvd) - Show clear error message with allowed characters - Add hint in rename dialog about valid characters - Prevent file system issues and avdmanager errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 07ae882 commit f0c0099

1 file changed

Lines changed: 52 additions & 7 deletions

File tree

src/main/java/net/nicolamurtas/android/emulator/AndroidEmulatorManager.java

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,25 @@ private void updateDeviceCards() {
547547
});
548548
}
549549

550+
/**
551+
* Validates AVD name to ensure it doesn't contain spaces or invalid characters.
552+
* AVD names should only contain letters, numbers, underscores, and hyphens.
553+
*/
554+
private boolean isValidAvdName(String name) {
555+
if (name == null || name.isEmpty()) {
556+
return false;
557+
}
558+
559+
// Check for spaces
560+
if (name.contains(" ")) {
561+
return false;
562+
}
563+
564+
// AVD names should only contain: letters, numbers, underscores, hyphens
565+
// Pattern: ^[a-zA-Z0-9_-]+$
566+
return name.matches("^[a-zA-Z0-9_-]+$");
567+
}
568+
550569
private void loadConfiguration() {
551570
Path sdkPath = configService.getSdkPath();
552571
sdkPathField.setText(sdkPath.toString());
@@ -783,20 +802,32 @@ private void createAvdDialog() {
783802
"Create New AVD", JOptionPane.OK_CANCEL_OPTION);
784803

785804
if (result == JOptionPane.OK_OPTION) {
805+
String avdName = nameField.getText().trim();
806+
807+
// Validate AVD name
808+
if (!isValidAvdName(avdName)) {
809+
JOptionPane.showMessageDialog(this,
810+
"Invalid AVD name!\n\n" +
811+
"The name cannot contain spaces or special characters.\n" +
812+
"Use letters, numbers, underscores, and hyphens only.",
813+
"Invalid Name", JOptionPane.ERROR_MESSAGE);
814+
return;
815+
}
816+
786817
new Thread(() -> {
787818
try {
788819
// Determine which API level to use (standard or legacy)
789820
String selectedApi = legacyCheckBox.isSelected() ?
790821
(String) legacyApiCombo.getSelectedItem() :
791822
(String) apiCombo.getSelectedItem();
792823

793-
log("Creating AVD: " + nameField.getText() + " (API " + selectedApi + ")");
824+
log("Creating AVD: " + avdName + " (API " + selectedApi + ")");
794825

795826
// Show progress bar for potential API installation
796827
showProgress(true);
797828

798829
boolean success = emulatorService.createAvd(
799-
nameField.getText(),
830+
avdName,
800831
selectedApi,
801832
(String) deviceCombo.getSelectedItem(),
802833
this::updateProgress
@@ -880,14 +911,28 @@ private void deleteAvdByName(String avdName) {
880911

881912
private void renameAvd(String oldName) {
882913
String newName = JOptionPane.showInputDialog(this,
883-
"Enter new name for AVD '" + oldName + "':",
914+
"Enter new name for AVD '" + oldName + "':\n\n" +
915+
"(letters, numbers, underscores, and hyphens only)",
884916
"Rename AVD",
885917
JOptionPane.PLAIN_MESSAGE);
886918

887919
if (newName != null && !newName.trim().isEmpty() && !newName.equals(oldName)) {
920+
newName = newName.trim();
921+
922+
// Validate AVD name
923+
if (!isValidAvdName(newName)) {
924+
JOptionPane.showMessageDialog(this,
925+
"Invalid AVD name!\n\n" +
926+
"The name cannot contain spaces or special characters.\n" +
927+
"Use letters, numbers, underscores, and hyphens only.",
928+
"Invalid Name", JOptionPane.ERROR_MESSAGE);
929+
return;
930+
}
931+
932+
String finalNewName = newName;
888933
new Thread(() -> {
889934
try {
890-
log("Renaming AVD: " + oldName + " -> " + newName);
935+
log("Renaming AVD: " + oldName + " -> " + finalNewName);
891936

892937
// Get AVD path
893938
EmulatorService.AvdInfo avdInfo = allAvds.stream()
@@ -902,8 +947,8 @@ private void renameAvd(String oldName) {
902947

903948
Path avdPath = Path.of(avdInfo.path());
904949
Path iniFile = avdPath.getParent().resolve(oldName + ".ini");
905-
Path newAvdPath = avdPath.getParent().resolve(newName + ".avd");
906-
Path newIniFile = avdPath.getParent().resolve(newName + ".ini");
950+
Path newAvdPath = avdPath.getParent().resolve(finalNewName + ".avd");
951+
Path newIniFile = avdPath.getParent().resolve(finalNewName + ".ini");
907952

908953
// Rename .avd directory
909954
if (Files.exists(avdPath)) {
@@ -915,7 +960,7 @@ private void renameAvd(String oldName) {
915960
Files.move(iniFile, newIniFile);
916961
// Update path in ini file
917962
String iniContent = Files.readString(newIniFile);
918-
iniContent = iniContent.replace(oldName + ".avd", newName + ".avd");
963+
iniContent = iniContent.replace(oldName + ".avd", finalNewName + ".avd");
919964
Files.writeString(newIniFile, iniContent);
920965
}
921966

0 commit comments

Comments
 (0)