diff --git a/src/main/scala/gitbucket/core/controller/AccountController.scala b/src/main/scala/gitbucket/core/controller/AccountController.scala index 139470232..5a427b377 100644 --- a/src/main/scala/gitbucket/core/controller/AccountController.scala +++ b/src/main/scala/gitbucket/core/controller/AccountController.scala @@ -61,31 +61,31 @@ trait AccountControllerBase extends AccountManagementControllerBase { val sshKeyForm = mapping( "title" -> trim(label("Title", text(required, maxlength(100)))), - "publicKey" -> trim(label("Key" , text(required, validPublicKey))) + "publicKey" -> trim2(label("Key" , text(required, validPublicKey))) )(SshKeyForm.apply) val personalTokenForm = mapping( - "note" -> trim(label("Token", text(required, maxlength(100)))) + "note" -> trim(label("Token", text(required, maxlength(100)))) )(PersonalTokenForm.apply) case class NewGroupForm(groupName: String, description: Option[String], url: Option[String], fileId: Option[String], members: String) case class EditGroupForm(groupName: String, description: Option[String], url: Option[String], fileId: Option[String], members: String, clearImage: Boolean) val newGroupForm = mapping( - "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier, uniqueUserName, reservedNames))), + "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier, uniqueUserName, reservedNames))), "description" -> trim(label("Group description", optional(text()))), - "url" -> trim(label("URL" ,optional(text(maxlength(200))))), - "fileId" -> trim(label("File ID" ,optional(text()))), - "members" -> trim(label("Members" ,text(required, members))) + "url" -> trim(label("URL" ,optional(text(maxlength(200))))), + "fileId" -> trim(label("File ID" ,optional(text()))), + "members" -> trim(label("Members" ,text(required, members))) )(NewGroupForm.apply) val editGroupForm = mapping( - "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier))), + "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier))), "description" -> trim(label("Group description", optional(text()))), - "url" -> trim(label("URL" ,optional(text(maxlength(200))))), - "fileId" -> trim(label("File ID" ,optional(text()))), - "members" -> trim(label("Members" ,text(required, members))), - "clearImage" -> trim(label("Clear image" ,boolean())) + "url" -> trim(label("URL" ,optional(text(maxlength(200))))), + "fileId" -> trim(label("File ID" ,optional(text()))), + "members" -> trim(label("Members" ,text(required, members))), + "clearImage" -> trim(label("Clear image" ,boolean())) )(EditGroupForm.apply) case class RepositoryCreationForm(owner: String, name: String, description: Option[String], isPrivate: Boolean, createReadme: Boolean) diff --git a/src/main/scala/gitbucket/core/controller/ControllerBase.scala b/src/main/scala/gitbucket/core/controller/ControllerBase.scala index ceff777f9..08a294193 100644 --- a/src/main/scala/gitbucket/core/controller/ControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/ControllerBase.scala @@ -159,6 +159,18 @@ abstract class ControllerBase extends ScalatraFilter if (path.startsWith("http")) path else baseUrl + super.url(path, params, false, false, false) + /** + * Extends scalatra-form's trim rule to eliminate CR and LF. + */ + protected def trim2[T](valueType: SingleValueType[T]): SingleValueType[T] = new SingleValueType[T](){ + def convert(value: String, messages: Messages): T = valueType.convert(trim(value), messages) + + override def validate(name: String, value: String, params: Map[String, String], messages: Messages): Seq[(String, String)] = + valueType.validate(name, trim(value), params, messages) + + private def trim(value: String): String = if(value == null) null else value.replaceAll("\r\n", "").trim + } + /** * Use this method to response the raw data against XSS. */ diff --git a/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala b/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala index 0ca0305c5..356de85d7 100644 --- a/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala @@ -63,7 +63,7 @@ trait RepositorySettingsControllerBase extends ControllerBase { val deployKeyForm = mapping( "title" -> trim(label("Title", text(required, maxlength(100)))), - "publicKey" -> trim(label("Key" , text(required))), // TODO duplication check in the repository? + "publicKey" -> trim2(label("Key" , text(required))), // TODO duplication check in the repository? "allowWrite" -> trim(label("Key" , boolean())) )(DeployKeyForm.apply) diff --git a/src/main/scala/gitbucket/core/ssh/SshUtil.scala b/src/main/scala/gitbucket/core/ssh/SshUtil.scala index 62eb97a7b..9563ab3c8 100644 --- a/src/main/scala/gitbucket/core/ssh/SshUtil.scala +++ b/src/main/scala/gitbucket/core/ssh/SshUtil.scala @@ -18,16 +18,17 @@ object SshUtil { val parts = key.split(" ") if (parts.size < 2) { logger.debug(s"Invalid PublicKey Format: ${key}") - return None - } - try { - val encodedKey = parts(1) - val decode = Base64.getDecoder.decode(Constants.encodeASCII(encodedKey)) - Some(new ByteArrayBuffer(decode).getRawPublicKey) - } catch { - case e: Throwable => - logger.debug(e.getMessage, e) - None + None + } else { + try { + val encodedKey = parts(1) + val decode = Base64.getDecoder.decode(Constants.encodeASCII(encodedKey)) + Some(new ByteArrayBuffer(decode).getRawPublicKey) + } catch { + case e: Throwable => + logger.debug(e.getMessage, e) + None + } } }