ctype.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include "crypto/ctype.h"
  12. #include <openssl/ebcdic.h>
  13. /*
  14. * Define the character classes for each character in the seven bit ASCII
  15. * character set. This is independent of the host's character set, characters
  16. * are converted to ASCII before being used as an index in to this table.
  17. * Characters outside of the seven bit ASCII range are detected before indexing.
  18. */
  19. static const unsigned short ctype_char_map[128] = {
  20. /* 00 nul */ CTYPE_MASK_cntrl,
  21. /* 01 soh */ CTYPE_MASK_cntrl,
  22. /* 02 stx */ CTYPE_MASK_cntrl,
  23. /* 03 etx */ CTYPE_MASK_cntrl,
  24. /* 04 eot */ CTYPE_MASK_cntrl,
  25. /* 05 enq */ CTYPE_MASK_cntrl,
  26. /* 06 ack */ CTYPE_MASK_cntrl,
  27. /* 07 \a */ CTYPE_MASK_cntrl,
  28. /* 08 \b */ CTYPE_MASK_cntrl,
  29. /* 09 \t */ CTYPE_MASK_blank | CTYPE_MASK_cntrl | CTYPE_MASK_space,
  30. /* 0A \n */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
  31. /* 0B \v */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
  32. /* 0C \f */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
  33. /* 0D \r */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
  34. /* 0E so */ CTYPE_MASK_cntrl,
  35. /* 0F si */ CTYPE_MASK_cntrl,
  36. /* 10 dle */ CTYPE_MASK_cntrl,
  37. /* 11 dc1 */ CTYPE_MASK_cntrl,
  38. /* 12 dc2 */ CTYPE_MASK_cntrl,
  39. /* 13 dc3 */ CTYPE_MASK_cntrl,
  40. /* 14 dc4 */ CTYPE_MASK_cntrl,
  41. /* 15 nak */ CTYPE_MASK_cntrl,
  42. /* 16 syn */ CTYPE_MASK_cntrl,
  43. /* 17 etb */ CTYPE_MASK_cntrl,
  44. /* 18 can */ CTYPE_MASK_cntrl,
  45. /* 19 em */ CTYPE_MASK_cntrl,
  46. /* 1A sub */ CTYPE_MASK_cntrl,
  47. /* 1B esc */ CTYPE_MASK_cntrl,
  48. /* 1C fs */ CTYPE_MASK_cntrl,
  49. /* 1D gs */ CTYPE_MASK_cntrl,
  50. /* 1E rs */ CTYPE_MASK_cntrl,
  51. /* 1F us */ CTYPE_MASK_cntrl,
  52. /* 20 */ CTYPE_MASK_blank | CTYPE_MASK_print | CTYPE_MASK_space
  53. | CTYPE_MASK_asn1print,
  54. /* 21 ! */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  55. /* 22 " */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  56. /* 23 # */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  57. /* 24 $ */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  58. /* 25 % */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  59. /* 26 & */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  60. /* 27 ' */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  61. | CTYPE_MASK_asn1print,
  62. /* 28 ( */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  63. | CTYPE_MASK_asn1print,
  64. /* 29 ) */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  65. | CTYPE_MASK_asn1print,
  66. /* 2A * */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  67. /* 2B + */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  68. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  69. /* 2C , */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  70. | CTYPE_MASK_asn1print,
  71. /* 2D - */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  72. | CTYPE_MASK_asn1print,
  73. /* 2E . */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  74. | CTYPE_MASK_asn1print,
  75. /* 2F / */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  76. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  77. /* 30 0 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  78. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  79. /* 31 1 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  80. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  81. /* 32 2 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  82. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  83. /* 33 3 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  84. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  85. /* 34 4 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  86. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  87. /* 35 5 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  88. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  89. /* 36 6 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  90. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  91. /* 37 7 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  92. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  93. /* 38 8 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  94. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  95. /* 39 9 */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
  96. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  97. /* 3A : */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  98. | CTYPE_MASK_asn1print,
  99. /* 3B ; */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  100. /* 3C < */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  101. /* 3D = */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  102. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  103. /* 3E > */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  104. /* 3F ? */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
  105. | CTYPE_MASK_asn1print,
  106. /* 40 @ */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  107. /* 41 A */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  108. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  109. /* 42 B */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  110. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  111. /* 43 C */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  112. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  113. /* 44 D */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  114. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  115. /* 45 E */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  116. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  117. /* 46 F */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  118. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  119. /* 47 G */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  120. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  121. /* 48 H */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  122. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  123. /* 49 I */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  124. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  125. /* 4A J */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  126. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  127. /* 4B K */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  128. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  129. /* 4C L */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  130. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  131. /* 4D M */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  132. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  133. /* 4E N */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  134. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  135. /* 4F O */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  136. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  137. /* 50 P */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  138. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  139. /* 51 Q */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  140. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  141. /* 52 R */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  142. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  143. /* 53 S */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  144. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  145. /* 54 T */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  146. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  147. /* 55 U */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  148. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  149. /* 56 V */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  150. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  151. /* 57 W */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  152. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  153. /* 58 X */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  154. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  155. /* 59 Y */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  156. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  157. /* 5A Z */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
  158. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  159. /* 5B [ */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  160. /* 5C \ */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  161. /* 5D ] */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  162. /* 5E ^ */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  163. /* 5F _ */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  164. /* 60 ` */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  165. /* 61 a */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  166. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  167. /* 62 b */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  168. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  169. /* 63 c */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  170. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  171. /* 64 d */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  172. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  173. /* 65 e */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  174. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  175. /* 66 f */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  176. | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  177. /* 67 g */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  178. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  179. /* 68 h */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  180. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  181. /* 69 i */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  182. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  183. /* 6A j */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  184. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  185. /* 6B k */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  186. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  187. /* 6C l */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  188. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  189. /* 6D m */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  190. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  191. /* 6E n */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  192. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  193. /* 6F o */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  194. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  195. /* 70 p */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  196. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  197. /* 71 q */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  198. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  199. /* 72 r */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  200. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  201. /* 73 s */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  202. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  203. /* 74 t */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  204. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  205. /* 75 u */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  206. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  207. /* 76 v */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  208. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  209. /* 77 w */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  210. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  211. /* 78 x */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  212. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  213. /* 79 y */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  214. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  215. /* 7A z */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
  216. | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
  217. /* 7B { */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  218. /* 7C | */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  219. /* 7D } */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  220. /* 7E ~ */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
  221. /* 7F del */ CTYPE_MASK_cntrl
  222. };
  223. #ifdef CHARSET_EBCDIC
  224. int ossl_toascii(int c)
  225. {
  226. if (c < -128 || c > 256 || c == EOF)
  227. return c;
  228. /*
  229. * Adjust negatively signed characters.
  230. * This is not required for ASCII because any character that sign extends
  231. * is not seven bit and all of the checks are on the seven bit characters.
  232. * I.e. any check must fail on sign extension.
  233. */
  234. if (c < 0)
  235. c += 256;
  236. return os_toascii[c];
  237. }
  238. int ossl_fromascii(int c)
  239. {
  240. if (c < -128 || c > 256 || c == EOF)
  241. return c;
  242. if (c < 0)
  243. c += 256;
  244. return os_toebcdic[c];
  245. }
  246. #endif
  247. int ossl_ctype_check(int c, unsigned int mask)
  248. {
  249. const int max = sizeof(ctype_char_map) / sizeof(*ctype_char_map);
  250. const int a = ossl_toascii(c);
  251. return a >= 0 && a < max && (ctype_char_map[a] & mask) != 0;
  252. }
  253. /*
  254. * Implement some of the simpler functions directly to avoid the overhead of
  255. * accessing memory via ctype_char_map[].
  256. */
  257. #define ASCII_IS_DIGIT(c) (c >= 0x30 && c <= 0x39)
  258. #define ASCII_IS_UPPER(c) (c >= 0x41 && c <= 0x5A)
  259. #define ASCII_IS_LOWER(c) (c >= 0x61 && c <= 0x7A)
  260. int ossl_isdigit(int c)
  261. {
  262. int a = ossl_toascii(c);
  263. return ASCII_IS_DIGIT(a);
  264. }
  265. int ossl_isupper(int c)
  266. {
  267. int a = ossl_toascii(c);
  268. return ASCII_IS_UPPER(a);
  269. }
  270. int ossl_islower(int c)
  271. {
  272. int a = ossl_toascii(c);
  273. return ASCII_IS_LOWER(a);
  274. }
  275. #if defined(CHARSET_EBCDIC) && !defined(CHARSET_EBCDIC_TEST)
  276. static const int case_change = 0x40;
  277. #else
  278. static const int case_change = 0x20;
  279. #endif
  280. int ossl_tolower(int c)
  281. {
  282. int a = ossl_toascii(c);
  283. return ASCII_IS_UPPER(a) ? c ^ case_change : c;
  284. }
  285. int ossl_toupper(int c)
  286. {
  287. int a = ossl_toascii(c);
  288. return ASCII_IS_LOWER(a) ? c ^ case_change : c;
  289. }
  290. int ossl_ascii_isdigit(int c)
  291. {
  292. return ASCII_IS_DIGIT(c);
  293. }