Validators.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "Validators.h"
  9. #include <QDir>
  10. #include <QMimeDatabase>
  11. #include <QRegularExpression>
  12. #define STANDARD_SUCCESS ProjectSettingsTool::FunctorValidator::ReturnType(QValidator::Acceptable, "");
  13. namespace
  14. {
  15. using RetType = ProjectSettingsTool::FunctorValidator::ReturnType;
  16. static const int noMaxLength = -1;
  17. static const int maxIosVersionLength = 18;
  18. static const int androidPublicAppKeyLength = 392;
  19. static const char* xmlRelativePath = "Code/Tools/RC/Config/rc/";
  20. static const char* xmlMimeType = "application/xml";
  21. static const char* stringEmpty = "String is empty";
  22. // Returns true if string is valid android package and apple bundle identifier
  23. RetType RegularExpressionValidator(const QString& pattern, const QString& name, int maxLength = noMaxLength)
  24. {
  25. if (maxLength != noMaxLength && name.length() > maxLength)
  26. {
  27. return RetType(QValidator::Invalid, QObject::tr("Cannot be longer than %1 characters.")
  28. .arg(QString::number(maxLength)));
  29. }
  30. else if (name.isEmpty())
  31. {
  32. return RetType(QValidator::Intermediate, QObject::tr(stringEmpty));
  33. }
  34. QRegularExpression regex(pattern);
  35. QRegularExpressionMatch match = regex.match(name, 0, QRegularExpression::PartialPreferCompleteMatch);
  36. if (match.hasMatch())
  37. {
  38. if (match.capturedLength(0) == name.length())
  39. {
  40. return STANDARD_SUCCESS;
  41. }
  42. else
  43. {
  44. return RetType(QValidator::Intermediate, "Input incorrect.");
  45. }
  46. }
  47. if (match.hasPartialMatch())
  48. {
  49. return RetType(QValidator::Intermediate, QObject::tr("Partially matches requirements."));
  50. }
  51. else
  52. {
  53. return RetType(QValidator::Invalid, QObject::tr("Fails to match requirements at all."));
  54. }
  55. }
  56. }
  57. namespace ProjectSettingsTool
  58. {
  59. namespace Validators
  60. {
  61. namespace Internal
  62. {
  63. // Returns true if file is readable and the correct mime type
  64. RetType FileReadableAndCorrectType(const QString& path, const QString& fileType)
  65. {
  66. QDir dirPath(path);
  67. if (dirPath.isReadable())
  68. {
  69. QMimeDatabase mimeDB;
  70. QMimeType mimeType = mimeDB.mimeTypeForFile(path);
  71. if (mimeType.name() == fileType)
  72. {
  73. return STANDARD_SUCCESS;
  74. }
  75. else
  76. {
  77. return RetType(QValidator::Intermediate, QObject::tr("File type should be %1, but is %2.")
  78. .arg(fileType).arg(mimeType.name()));
  79. }
  80. }
  81. else
  82. {
  83. return RetType(QValidator::Intermediate, QObject::tr("File is not readable."));
  84. }
  85. }
  86. } // namespace Internal
  87. // Returns true if valid cross platform file or directory name
  88. RetType FileName(const QString& name)
  89. {
  90. // There was a known issue on android with '.' used in directory names
  91. // causing problems so it has been omitted from use
  92. return RegularExpressionValidator("[\\w,-]+", name);
  93. }
  94. // Returns true if valid iOS file or directory name
  95. RetType IOSFileName(const QString& name)
  96. {
  97. return RegularExpressionValidator("[\\w,-.]+", name);
  98. }
  99. RetType FileNameOrEmpty(const QString& name)
  100. {
  101. if (IsNotEmpty(name).first == QValidator::Acceptable)
  102. {
  103. return FileName(name);
  104. }
  105. else
  106. {
  107. return STANDARD_SUCCESS;
  108. }
  109. }
  110. // Returns true if string isn't empty
  111. RetType IsNotEmpty(const QString& value)
  112. {
  113. if (!value.isEmpty())
  114. {
  115. return STANDARD_SUCCESS;
  116. }
  117. else
  118. {
  119. return RetType(QValidator::Intermediate, QObject::tr(stringEmpty));
  120. }
  121. }
  122. // Returns true if string is valid as a boolean
  123. RetType BoolString(const QString& value)
  124. {
  125. if (value == "true" || value == "false")
  126. {
  127. return STANDARD_SUCCESS;
  128. }
  129. return RetType(QValidator::Invalid, QObject::tr("Invalid bool string."));
  130. }
  131. // Returns true if string is valid android package and apple bundle identifier
  132. RetType PackageName(const QString& name)
  133. {
  134. return RegularExpressionValidator("[a-zA-Z][A-Za-z0-9]*(\\.[a-zA-Z][A-Za-z0-9]*)+", name);
  135. }
  136. // Returns true if valid android version number
  137. RetType VersionNumber(const QString& value)
  138. {
  139. // Error handling built in already
  140. int ver = value.toInt();
  141. if (0 >= ver)
  142. {
  143. return RetType(QValidator::Invalid, QObject::tr("Version must be greater than 0."));
  144. }
  145. else if (ver > maxAndroidVersion)
  146. {
  147. return RetType(QValidator::Invalid, QObject::tr("Version must be less than or equal to %1.")
  148. .arg(QString::number(maxAndroidVersion)));
  149. }
  150. else
  151. {
  152. return STANDARD_SUCCESS;
  153. }
  154. }
  155. // Returns true if valid ios version number
  156. RetType IOSVersionNumber(const QString& value)
  157. {
  158. // support up to 4-component numerical-only version strings
  159. return RegularExpressionValidator
  160. ("^(\\d+)(\\.\\d+){0,3}$",
  161. value,
  162. maxIosVersionLength);
  163. }
  164. // Returns true if Public App Key is valid length
  165. RetType PublicAppKeyOrEmpty(const QString& value)
  166. {
  167. // If anyone knows that public app keys are not always 392 chars long
  168. // then this MUST be changed
  169. if (value.isEmpty() || value.length() == androidPublicAppKeyLength)
  170. {
  171. return STANDARD_SUCCESS;
  172. }
  173. else
  174. {
  175. return RetType(QValidator::Intermediate, QObject::tr("App key should be %1 characters long.")
  176. .arg(QString::number(androidPublicAppKeyLength)));
  177. }
  178. }
  179. // Returns true if path is empty or a valid xml file relative to <build dir>
  180. RetType ValidXmlOrEmpty(const QString& path)
  181. {
  182. if (IsNotEmpty(path).first == QValidator::Acceptable)
  183. {
  184. return Internal::FileReadableAndCorrectType(xmlRelativePath + path, xmlMimeType);
  185. }
  186. else
  187. {
  188. return STANDARD_SUCCESS;
  189. }
  190. }
  191. // Returns true if path is empty or a valid png file
  192. RetType ValidPngOrEmpty(const QString& path)
  193. {
  194. if (IsNotEmpty(path).first == QValidator::Acceptable)
  195. {
  196. return Internal::FileReadableAndCorrectType(path, pngMimeType);
  197. }
  198. else
  199. {
  200. return STANDARD_SUCCESS;
  201. }
  202. }
  203. } // namespace Validators
  204. } // namespace ProjectSettingsTool