2
0

java_sig_parser.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*
  2. * Copyright (C) 2013 Konstantin Mosesov
  3. *
  4. * This file is part of Kamailio, a free SIP server.
  5. *
  6. * This file is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. *
  12. * This file is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <float.h>
  25. #include "../../str.h"
  26. #include "../../sr_module.h"
  27. #include <jni.h>
  28. #include "global.h"
  29. #include "utils.h"
  30. #include "app_java_mod.h"
  31. #include "java_iface.h"
  32. #include "java_support.h"
  33. #include "java_native_methods.h"
  34. #include "java_sig_parser.h"
  35. int is_sig_allowed(char *s)
  36. {
  37. if (s == NULL || strlen(s) < 1)
  38. return 0;
  39. if (!strcmp(s, " ") || !strcmp(s, "\n") || !strcmp(s, "\r") || !strcmp(s, "\t"))
  40. {
  41. LM_ERR("%s: signature error: '%s' contains whitespaces or any unparsable chars.\n", APP_NAME, s);
  42. return 0;
  43. }
  44. // LM_ERR("s='%s', strlen(s)=%d\n", s, strlen(s));
  45. if (strlen(s) == 1) // signature is single modifier (primitive)
  46. {
  47. if (!strcmp(s, "[")) // invalid signature modifier definition
  48. {
  49. LM_ERR("%s: signature error: '%s': no type of array specified.\n", APP_NAME, s);
  50. return 0;
  51. }
  52. if (!strcmp(s, "L")) // invalid signature modifier definition
  53. {
  54. LM_ERR("%s: signature error '%s': no object specified.\n", APP_NAME, s);
  55. return 0;
  56. }
  57. #ifndef JAVA_INV_SUPP_TYPE_VOID
  58. if (!strcmp(s, "V"))
  59. {
  60. LM_ERR("%s: signature error '%s': no object specified.\n", APP_NAME, s);
  61. return 0;
  62. }
  63. #endif
  64. }
  65. else // a complex signature (object)
  66. {
  67. #ifndef JAVA_INV_SUPP_TYPE_ARRAYS
  68. if (strcmp(s, "[") > 0)
  69. {
  70. LM_ERR("%s: signature error: '%s' denotes array which isn't supported yet.\n", APP_NAME, s);
  71. return 0;
  72. }
  73. #endif
  74. if (strrchr(&s[0], 'L') > 0)
  75. {
  76. #ifndef JAVA_INV_SUPP_TYPE_OBJECTS
  77. LM_ERR("%s: signature error: '%s' denotes object which isn't supported yet.\n", APP_NAME, s);
  78. return 0;
  79. #else
  80. int f = 0;
  81. #ifdef JAVA_INV_SUPP_TYPE_BOOLEAN
  82. if (!strcmp(s, "Ljava/lang/Boolean;"))
  83. f = 1;
  84. #endif
  85. #ifdef JAVA_INV_SUPP_TYPE_BYTE
  86. if (!strcmp(s, "Ljava/lang/Byte;"))
  87. f = 1;
  88. #endif
  89. #ifdef JAVA_INV_SUPP_TYPE_CHARACTER
  90. if (!strcmp(s, "Ljava/lang/Character;"))
  91. f = 1;
  92. #endif
  93. #ifdef JAVA_INV_SUPP_TYPE_DOUBLE
  94. if (!strcmp(s, "Ljava/lang/Double;"))
  95. f = 1;
  96. #endif
  97. #ifdef JAVA_INV_SUPP_TYPE_FLOAT
  98. if (!strcmp(s, "Ljava/lang/Float;"))
  99. f = 1;
  100. #endif
  101. #ifdef JAVA_INV_SUPP_TYPE_INTEGER
  102. if (!strcmp(s, "Ljava/lang/Integer;"))
  103. f = 1;
  104. #endif
  105. #ifdef JAVA_INV_SUPP_TYPE_LONG
  106. if (!strcmp(s, "Ljava/lang/Long;"))
  107. f = 1;
  108. #endif
  109. #ifdef JAVA_INV_SUPP_TYPE_SHORT
  110. if (!strcmp(s, "Ljava/lang/Short;"))
  111. f = 1;
  112. #endif
  113. #ifdef JAVA_INV_SUPP_TYPE_STRING
  114. if (!strcmp(s, "Ljava/lang/String;"))
  115. f = 1;
  116. #endif
  117. if (f == 0)
  118. {
  119. LM_ERR("%s: signature '%s' isn't supported yet.\n", APP_NAME, s);
  120. return 0;
  121. }
  122. #endif
  123. }
  124. }
  125. return 1;
  126. }
  127. static char *get_conv_err_str(int en)
  128. {
  129. switch(en)
  130. {
  131. case EINVAL: return "The value of base constant is not supported or no conversion could be performed";
  132. case ERANGE: return "The given string was out of range; the value converted has been clamped.";
  133. default: return "General parse error";
  134. }
  135. }
  136. /* explaination of jvalue fields:
  137. typedef union jvalue {
  138. jboolean z;
  139. jbyte b;
  140. jchar c;
  141. jshort s;
  142. jint i;
  143. jlong j;
  144. jfloat f;
  145. jdouble d;
  146. jobject l;
  147. } jvalue;
  148. */
  149. jvalue *get_value_by_sig_type(char *sig, char *pval)
  150. {
  151. char *endptr;
  152. char scptr;
  153. int siptr;
  154. long slptr;
  155. short ssptr;
  156. double sdptr;
  157. float sfptr;
  158. jstring sjptr;
  159. jvalue *ret;
  160. ret = (jvalue *)pkg_malloc(sizeof(jvalue));
  161. if (!ret)
  162. {
  163. LM_ERR("%s: pkg_malloc() has failed. Not enouph memory!\n", APP_NAME);
  164. return NULL;
  165. }
  166. if (sig == NULL || strlen(sig) <= 0)
  167. {
  168. LM_ERR("%s: Can't process empty or NULL signature.\n", APP_NAME);
  169. pkg_free(ret);
  170. return NULL;
  171. }
  172. if (pval == NULL || strlen(pval) <= 0)
  173. {
  174. LM_ERR("%s: Can't process empty or NULL parameter value.\n", APP_NAME);
  175. pkg_free(ret);
  176. return NULL;
  177. }
  178. // boolean
  179. if (!strncmp(sig, "Z", 1)
  180. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_BOOLEAN)
  181. || !strcmp(sig, "Ljava/lang/Boolean;")
  182. #endif
  183. ) {
  184. if (!strncasecmp(pval, "true", 4))
  185. (*ret).z = (jboolean)JNI_TRUE;
  186. /* comment this block to avoid conversation '1' to 'true' */
  187. else if (!strncmp(pval, "1", 1))
  188. (*ret).z = (jboolean)JNI_TRUE;
  189. else if (!strncasecmp(pval, "false", 5))
  190. (*ret).z = (jboolean)JNI_FALSE;
  191. /* comment this block to avoid conversation '0' to 'false' */
  192. else if (!strncmp(pval, "0", 1))
  193. (*ret).z = (jboolean)JNI_FALSE;
  194. else
  195. {
  196. LM_ERR("%s: Can't cast '%s' to type '%s'.\n", APP_NAME, pval, sig);
  197. pkg_free(ret);
  198. return NULL;
  199. }
  200. return ret;
  201. }
  202. else
  203. // byte
  204. if (!strncmp(sig, "B", 1)
  205. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_BYTE)
  206. || !strcmp(sig, "Ljava/lang/Byte;")
  207. #endif
  208. ) {
  209. // skptr = (signed char)char2jbyte(pval);
  210. sscanf(pval, "%x", &siptr);
  211. if (siptr == 0 && errno != 0)
  212. {
  213. LM_ERR("%s: Can't cast '%s' to type '%s'. Error: %s.\n", APP_NAME, pval, sig, get_conv_err_str(errno));
  214. pkg_free(ret);
  215. return NULL;
  216. }
  217. if (siptr < SCHAR_MAX || siptr > SCHAR_MAX)
  218. {
  219. LM_ERR("%s: Can't cast '%s' to type '%s'. Reason: overflow.", APP_NAME, pval, sig);
  220. pkg_free(ret);
  221. return NULL;
  222. }
  223. (*ret).b = (jbyte)siptr;
  224. return ret;
  225. }
  226. else
  227. // char
  228. if (!strncmp(sig, "C", 1)
  229. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_CHARACTER)
  230. || !strcmp(sig, "Ljava/lang/Character;")
  231. #endif
  232. ) {
  233. sscanf(pval, "%c", &scptr);
  234. if (scptr == 0 && errno != 0)
  235. {
  236. LM_ERR("%s: Can't cast '%s' to type '%s'. Error: %s.\n", APP_NAME, pval, sig, get_conv_err_str(errno));
  237. pkg_free(ret);
  238. return NULL;
  239. }
  240. if (scptr < CHAR_MIN || scptr > CHAR_MAX) // overflow
  241. {
  242. LM_ERR("%s: Can't cast '%s' to type '%s'. Reason: overflow.", APP_NAME, pval, sig);
  243. pkg_free(ret);
  244. return NULL;
  245. }
  246. (*ret).c = (jchar)scptr;
  247. return ret;
  248. }
  249. else
  250. // double
  251. if (!strncmp(sig, "D", 1)
  252. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_DOUBLE)
  253. || !strcmp(sig, "Ljava/lang/Double;")
  254. #endif
  255. ) {
  256. sdptr = (double)strtod(pval, &endptr);
  257. if ((sdptr == 0 && errno != 0) || (pval == endptr))
  258. {
  259. LM_ERR("%s: Can't cast '%s' to type '%s'. Error: %s.\n", APP_NAME, pval, sig, get_conv_err_str(errno));
  260. pkg_free(ret);
  261. return NULL;
  262. }
  263. if (sdptr < LLONG_MIN || sdptr > LLONG_MAX) // overflow
  264. {
  265. LM_ERR("%s: Can't cast '%s' to type '%s'. Reason: overflow.", APP_NAME, pval, sig);
  266. pkg_free(ret);
  267. return NULL;
  268. }
  269. (*ret).d = (jdouble)sdptr;
  270. return ret;
  271. }
  272. else
  273. // float
  274. if (!strncmp(sig, "F", 1)
  275. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_FLOAT)
  276. || !strcmp(sig, "Ljava/lang/Float;")
  277. #endif
  278. ) {
  279. sfptr = (float)strtof(pval, &endptr);
  280. if ((sfptr == 0 && errno != 0) || (pval == endptr))
  281. {
  282. LM_ERR("%s: Can't cast '%s' to type '%s'. Error: %s.\n", APP_NAME, pval, sig, get_conv_err_str(errno));
  283. pkg_free(ret);
  284. return NULL;
  285. }
  286. if (sfptr < FLT_MIN || sfptr > FLT_MAX) // overflow
  287. {
  288. LM_ERR("%s: Can't cast '%s' to type '%s'. Reason: overflow.", APP_NAME, pval, sig);
  289. pkg_free(ret);
  290. return NULL;
  291. }
  292. (*ret).f = (jfloat)sfptr;
  293. return ret;
  294. }
  295. else
  296. // integer
  297. if (!strncmp(sig, "I", 1)
  298. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_INTEGER)
  299. || !strcmp(sig, "Ljava/lang/Integer;")
  300. #endif
  301. ) {
  302. slptr = strtol(pval, &endptr, 10);
  303. if ((slptr == 0 && errno != 0) || (pval == endptr))
  304. {
  305. LM_ERR("%s: Can't cast '%s' to type '%s'. Error: %s.\n", APP_NAME, pval, sig, get_conv_err_str(errno));
  306. pkg_free(ret);
  307. return NULL;
  308. }
  309. if (slptr < INT_MIN || slptr > INT_MAX) // overflow
  310. {
  311. LM_ERR("%s: Can't cast '%s' to type '%s'. Reason: overflow.", APP_NAME, pval, sig);
  312. pkg_free(ret);
  313. return NULL;
  314. }
  315. (*ret).i = (jint)slptr;
  316. return ret;
  317. }
  318. else
  319. // long
  320. if (!strncmp(sig, "J", 1)
  321. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_LONG)
  322. || !strcmp(sig, "Ljava/lang/Long;")
  323. #endif
  324. ) {
  325. slptr = (long)strtol(pval, &endptr, 10);
  326. if ((slptr == 0 && errno != 0) || (pval == endptr))
  327. {
  328. LM_ERR("%s: Can't cast '%s' to type '%s'. Error: %s.\n", APP_NAME, pval, sig, get_conv_err_str(errno));
  329. pkg_free(ret);
  330. return NULL;
  331. }
  332. if (slptr < LONG_MIN || slptr > LONG_MAX) // overflow
  333. {
  334. LM_ERR("%s: Can't cast '%s' to type '%s'. Reason: overflow.", APP_NAME, pval, sig);
  335. pkg_free(ret);
  336. return NULL;
  337. }
  338. (*ret).j = (jlong)slptr;
  339. return ret;
  340. }
  341. else
  342. // short
  343. if (!strncmp(sig, "S", 1)
  344. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_SHORT)
  345. || !strcmp(sig, "Ljava/lang/Short;")
  346. #endif
  347. ) {
  348. ssptr = (short)strtod(pval, &endptr);
  349. if ((ssptr == 0 && errno != 0) || (pval == endptr))
  350. {
  351. LM_ERR("%s: Can't cast '%s' to type '%s'. Error: %s.\n", APP_NAME, pval, sig, get_conv_err_str(errno));
  352. pkg_free(ret);
  353. return NULL;
  354. }
  355. if (ssptr < SHRT_MIN || ssptr > SHRT_MAX) // overflow
  356. {
  357. LM_ERR("%s: Can't cast '%s' to type '%s'. Reason: overflow.", APP_NAME, pval, sig);
  358. pkg_free(ret);
  359. return NULL;
  360. }
  361. (*ret).s = (jshort)ssptr;
  362. return ret;
  363. }
  364. // String (object)
  365. #if defined(JAVA_INV_SUPP_TYPE_OBJECTS) && defined(JAVA_INV_SUPP_TYPE_STRING)
  366. else
  367. if (!strcmp(sig, "Ljava/lang/String;"))
  368. {
  369. sjptr = (*env)->NewStringUTF(env, pval);
  370. if ((*env)->ExceptionCheck(env))
  371. {
  372. pkg_free(ret);
  373. handle_exception();
  374. return NULL;
  375. }
  376. /*
  377. if (pval != NULL && sjptr == NULL)
  378. {
  379. pkg_free(ret);
  380. return NULL;
  381. }
  382. */
  383. (*ret).l = (jstring)sjptr;
  384. return ret;
  385. }
  386. #endif
  387. #ifdef JAVA_INV_SUPP_TYPE_VOID
  388. else
  389. if (!strncmp(sig, "V", 1))
  390. {
  391. pkg_free(ret);
  392. return NULL;
  393. }
  394. #endif
  395. else
  396. {
  397. // unknown sig
  398. LM_ERR("%s: Can't cast '%s' to signature '%s'\n", APP_NAME, pval, sig);
  399. pkg_free(ret);
  400. return NULL;
  401. }
  402. return NULL;
  403. }