PageRenderTime 293ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llui/lltextvalidate.cpp

https://bitbucket.org/lindenlab/viewer-release/
C++ | 347 lines | 274 code | 30 blank | 43 comment | 66 complexity | 06864d952dacf9e69be60b0811844d22 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. /**
  2. * @file lltextvalidate.cpp
  3. * @brief Text validation helper functions
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. // Text editor widget to let users enter a single line.
  27. #include "linden_common.h"
  28. #include "lltextvalidate.h"
  29. #include "llresmgr.h" // for LLLocale
  30. namespace LLTextValidate
  31. {
  32. void ValidateTextNamedFuncs::declareValues()
  33. {
  34. declare("ascii", validateASCII);
  35. declare("float", validateFloat);
  36. declare("int", validateInt);
  37. declare("positive_s32", validatePositiveS32);
  38. declare("non_negative_s32", validateNonNegativeS32);
  39. declare("alpha_num", validateAlphaNum);
  40. declare("alpha_num_space", validateAlphaNumSpace);
  41. declare("ascii_printable_no_pipe", validateASCIIPrintableNoPipe);
  42. declare("ascii_printable_no_space", validateASCIIPrintableNoSpace);
  43. declare("ascii_with_newline", validateASCIIWithNewLine);
  44. }
  45. // Limits what characters can be used to [1234567890.-] with [-] only valid in the first position.
  46. // Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
  47. // the simple reasons that intermediate states may be invalid even if the final result is valid.
  48. //
  49. bool validateFloat(const LLWString &str)
  50. {
  51. LLLocale locale(LLLocale::USER_LOCALE);
  52. bool success = TRUE;
  53. LLWString trimmed = str;
  54. LLWStringUtil::trim(trimmed);
  55. S32 len = trimmed.length();
  56. if( 0 < len )
  57. {
  58. // May be a comma or period, depending on the locale
  59. llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
  60. S32 i = 0;
  61. // First character can be a negative sign
  62. if( '-' == trimmed[0] )
  63. {
  64. i++;
  65. }
  66. for( ; i < len; i++ )
  67. {
  68. if( (decimal_point != trimmed[i] ) && !LLStringOps::isDigit( trimmed[i] ) )
  69. {
  70. success = FALSE;
  71. break;
  72. }
  73. }
  74. }
  75. return success;
  76. }
  77. // Limits what characters can be used to [1234567890-] with [-] only valid in the first position.
  78. // Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
  79. // the simple reasons that intermediate states may be invalid even if the final result is valid.
  80. //
  81. bool validateInt(const LLWString &str)
  82. {
  83. LLLocale locale(LLLocale::USER_LOCALE);
  84. bool success = TRUE;
  85. LLWString trimmed = str;
  86. LLWStringUtil::trim(trimmed);
  87. S32 len = trimmed.length();
  88. if( 0 < len )
  89. {
  90. S32 i = 0;
  91. // First character can be a negative sign
  92. if( '-' == trimmed[0] )
  93. {
  94. i++;
  95. }
  96. for( ; i < len; i++ )
  97. {
  98. if( !LLStringOps::isDigit( trimmed[i] ) )
  99. {
  100. success = FALSE;
  101. break;
  102. }
  103. }
  104. }
  105. return success;
  106. }
  107. bool validatePositiveS32(const LLWString &str)
  108. {
  109. LLLocale locale(LLLocale::USER_LOCALE);
  110. LLWString trimmed = str;
  111. LLWStringUtil::trim(trimmed);
  112. S32 len = trimmed.length();
  113. bool success = TRUE;
  114. if(0 < len)
  115. {
  116. if(('-' == trimmed[0]) || ('0' == trimmed[0]))
  117. {
  118. success = FALSE;
  119. }
  120. S32 i = 0;
  121. while(success && (i < len))
  122. {
  123. if(!LLStringOps::isDigit(trimmed[i++]))
  124. {
  125. success = FALSE;
  126. }
  127. }
  128. }
  129. if (success)
  130. {
  131. S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
  132. if (val <= 0)
  133. {
  134. success = FALSE;
  135. }
  136. }
  137. return success;
  138. }
  139. bool validateNonNegativeS32(const LLWString &str)
  140. {
  141. LLLocale locale(LLLocale::USER_LOCALE);
  142. LLWString trimmed = str;
  143. LLWStringUtil::trim(trimmed);
  144. S32 len = trimmed.length();
  145. bool success = TRUE;
  146. if(0 < len)
  147. {
  148. if('-' == trimmed[0])
  149. {
  150. success = FALSE;
  151. }
  152. S32 i = 0;
  153. while(success && (i < len))
  154. {
  155. if(!LLStringOps::isDigit(trimmed[i++]))
  156. {
  157. success = FALSE;
  158. }
  159. }
  160. }
  161. if (success)
  162. {
  163. S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
  164. if (val < 0)
  165. {
  166. success = FALSE;
  167. }
  168. }
  169. return success;
  170. }
  171. bool validateNonNegativeS32NoSpace(const LLWString &str)
  172. {
  173. LLLocale locale(LLLocale::USER_LOCALE);
  174. LLWString test_str = str;
  175. S32 len = test_str.length();
  176. bool success = TRUE;
  177. if(0 < len)
  178. {
  179. if('-' == test_str[0])
  180. {
  181. success = FALSE;
  182. }
  183. S32 i = 0;
  184. while(success && (i < len))
  185. {
  186. if(!LLStringOps::isDigit(test_str[i]) || LLStringOps::isSpace(test_str[i++]))
  187. {
  188. success = FALSE;
  189. }
  190. }
  191. }
  192. if (success)
  193. {
  194. S32 val = strtol(wstring_to_utf8str(test_str).c_str(), NULL, 10);
  195. if (val < 0)
  196. {
  197. success = FALSE;
  198. }
  199. }
  200. return success;
  201. }
  202. bool validateAlphaNum(const LLWString &str)
  203. {
  204. LLLocale locale(LLLocale::USER_LOCALE);
  205. bool rv = TRUE;
  206. S32 len = str.length();
  207. if(len == 0) return rv;
  208. while(len--)
  209. {
  210. if( !LLStringOps::isAlnum((char)str[len]) )
  211. {
  212. rv = FALSE;
  213. break;
  214. }
  215. }
  216. return rv;
  217. }
  218. bool validateAlphaNumSpace(const LLWString &str)
  219. {
  220. LLLocale locale(LLLocale::USER_LOCALE);
  221. bool rv = TRUE;
  222. S32 len = str.length();
  223. if(len == 0) return rv;
  224. while(len--)
  225. {
  226. if(!(LLStringOps::isAlnum((char)str[len]) || (' ' == str[len])))
  227. {
  228. rv = FALSE;
  229. break;
  230. }
  231. }
  232. return rv;
  233. }
  234. // Used for most names of things stored on the server, due to old file-formats
  235. // that used the pipe (|) for multiline text storage. Examples include
  236. // inventory item names, parcel names, object names, etc.
  237. bool validateASCIIPrintableNoPipe(const LLWString &str)
  238. {
  239. bool rv = TRUE;
  240. S32 len = str.length();
  241. if(len == 0) return rv;
  242. while(len--)
  243. {
  244. llwchar wc = str[len];
  245. if (wc < 0x20
  246. || wc > 0x7f
  247. || wc == '|')
  248. {
  249. rv = FALSE;
  250. break;
  251. }
  252. if(!(wc == ' '
  253. || LLStringOps::isAlnum((char)wc)
  254. || LLStringOps::isPunct((char)wc) ) )
  255. {
  256. rv = FALSE;
  257. break;
  258. }
  259. }
  260. return rv;
  261. }
  262. // Used for avatar names
  263. bool validateASCIIPrintableNoSpace(const LLWString &str)
  264. {
  265. bool rv = TRUE;
  266. S32 len = str.length();
  267. if(len == 0) return rv;
  268. while(len--)
  269. {
  270. llwchar wc = str[len];
  271. if (wc < 0x20
  272. || wc > 0x7f
  273. || LLStringOps::isSpace(wc))
  274. {
  275. rv = FALSE;
  276. break;
  277. }
  278. if( !(LLStringOps::isAlnum((char)str[len]) ||
  279. LLStringOps::isPunct((char)str[len]) ) )
  280. {
  281. rv = FALSE;
  282. break;
  283. }
  284. }
  285. return rv;
  286. }
  287. bool validateASCII(const LLWString &str)
  288. {
  289. bool rv = TRUE;
  290. S32 len = str.length();
  291. while(len--)
  292. {
  293. if (str[len] < 0x20 || str[len] > 0x7f)
  294. {
  295. rv = FALSE;
  296. break;
  297. }
  298. }
  299. return rv;
  300. }
  301. // Used for multiline text stored on the server.
  302. // Example is landmark description in Places SP.
  303. bool validateASCIIWithNewLine(const LLWString &str)
  304. {
  305. bool rv = TRUE;
  306. S32 len = str.length();
  307. while(len--)
  308. {
  309. if ((str[len] < 0x20 && str[len] != 0xA) || str[len] > 0x7f)
  310. {
  311. rv = FALSE;
  312. break;
  313. }
  314. }
  315. return rv;
  316. }
  317. }