1
0

amf.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318
  1. /*
  2. * Copyright (C) 2005-2008 Team XBMC
  3. * http://www.xbmc.org
  4. * Copyright (C) 2008-2009 Andrej Stepanchuk
  5. * Copyright (C) 2009-2010 Howard Chu
  6. *
  7. * This file is part of librtmp.
  8. *
  9. * librtmp is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as
  11. * published by the Free Software Foundation; either version 2.1,
  12. * or (at your option) any later version.
  13. *
  14. * librtmp 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
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with librtmp see the file COPYING. If not, write to
  21. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  22. * Boston, MA 02110-1301, USA.
  23. * http://www.gnu.org/copyleft/lgpl.html
  24. */
  25. #include "rtmp_sys.h"
  26. #include "amf.h"
  27. #include "log.h"
  28. #include "bytes.h"
  29. static const AMFObjectProperty AMFProp_Invalid = { {0, 0}, AMF_INVALID };
  30. static const AMFObject AMFObj_Invalid = { 0, 0 };
  31. static const AVal AV_empty = { 0, 0 };
  32. /* Data is Big-Endian */
  33. unsigned short
  34. AMF_DecodeInt16(const char *data)
  35. {
  36. unsigned char *c = (unsigned char *) data;
  37. unsigned short val;
  38. val = (c[0] << 8) | c[1];
  39. return val;
  40. }
  41. unsigned int
  42. AMF_DecodeInt24(const char *data)
  43. {
  44. unsigned char *c = (unsigned char *) data;
  45. unsigned int val;
  46. val = (c[0] << 16) | (c[1] << 8) | c[2];
  47. return val;
  48. }
  49. unsigned int
  50. AMF_DecodeInt32(const char *data)
  51. {
  52. unsigned char *c = (unsigned char *)data;
  53. unsigned int val;
  54. val = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
  55. return val;
  56. }
  57. void
  58. AMF_DecodeString(const char *data, AVal *bv)
  59. {
  60. bv->av_len = AMF_DecodeInt16(data);
  61. bv->av_val = (bv->av_len > 0) ? (char *)data + 2 : NULL;
  62. }
  63. void
  64. AMF_DecodeLongString(const char *data, AVal *bv)
  65. {
  66. bv->av_len = AMF_DecodeInt32(data);
  67. bv->av_val = (bv->av_len > 0) ? (char *)data + 4 : NULL;
  68. }
  69. double
  70. AMF_DecodeNumber(const char *data)
  71. {
  72. double dVal;
  73. #if __FLOAT_WORD_ORDER == __BYTE_ORDER
  74. #if __BYTE_ORDER == __BIG_ENDIAN
  75. memcpy(&dVal, data, 8);
  76. #elif __BYTE_ORDER == __LITTLE_ENDIAN
  77. unsigned char *ci, *co;
  78. ci = (unsigned char *)data;
  79. co = (unsigned char *)&dVal;
  80. co[0] = ci[7];
  81. co[1] = ci[6];
  82. co[2] = ci[5];
  83. co[3] = ci[4];
  84. co[4] = ci[3];
  85. co[5] = ci[2];
  86. co[6] = ci[1];
  87. co[7] = ci[0];
  88. #endif
  89. #else
  90. #if __BYTE_ORDER == __LITTLE_ENDIAN /* __FLOAT_WORD_ORER == __BIG_ENDIAN */
  91. unsigned char *ci, *co;
  92. ci = (unsigned char *)data;
  93. co = (unsigned char *)&dVal;
  94. co[0] = ci[3];
  95. co[1] = ci[2];
  96. co[2] = ci[1];
  97. co[3] = ci[0];
  98. co[4] = ci[7];
  99. co[5] = ci[6];
  100. co[6] = ci[5];
  101. co[7] = ci[4];
  102. #else /* __BYTE_ORDER == __BIG_ENDIAN && __FLOAT_WORD_ORER == __LITTLE_ENDIAN */
  103. unsigned char *ci, *co;
  104. ci = (unsigned char *)data;
  105. co = (unsigned char *)&dVal;
  106. co[0] = ci[4];
  107. co[1] = ci[5];
  108. co[2] = ci[6];
  109. co[3] = ci[7];
  110. co[4] = ci[0];
  111. co[5] = ci[1];
  112. co[6] = ci[2];
  113. co[7] = ci[3];
  114. #endif
  115. #endif
  116. return dVal;
  117. }
  118. int
  119. AMF_DecodeBoolean(const char *data)
  120. {
  121. return *data != 0;
  122. }
  123. char *
  124. AMF_EncodeInt16(char *output, char *outend, short nVal)
  125. {
  126. if (output+2 > outend)
  127. return NULL;
  128. output[1] = nVal & 0xff;
  129. output[0] = nVal >> 8;
  130. return output+2;
  131. }
  132. char *
  133. AMF_EncodeInt24(char *output, char *outend, int nVal)
  134. {
  135. if (output+3 > outend)
  136. return NULL;
  137. output[2] = nVal & 0xff;
  138. output[1] = nVal >> 8;
  139. output[0] = nVal >> 16;
  140. return output+3;
  141. }
  142. char *
  143. AMF_EncodeInt32(char *output, char *outend, int nVal)
  144. {
  145. if (output+4 > outend)
  146. return NULL;
  147. output[3] = nVal & 0xff;
  148. output[2] = nVal >> 8;
  149. output[1] = nVal >> 16;
  150. output[0] = nVal >> 24;
  151. return output+4;
  152. }
  153. char *
  154. AMF_EncodeString(char *output, char *outend, const AVal *bv)
  155. {
  156. if ((bv->av_len < 65536 && output + 1 + 2 + bv->av_len > outend) ||
  157. output + 1 + 4 + bv->av_len > outend)
  158. return NULL;
  159. if (bv->av_len < 65536)
  160. {
  161. *output++ = AMF_STRING;
  162. output = AMF_EncodeInt16(output, outend, bv->av_len);
  163. }
  164. else
  165. {
  166. *output++ = AMF_LONG_STRING;
  167. output = AMF_EncodeInt32(output, outend, bv->av_len);
  168. }
  169. memcpy(output, bv->av_val, bv->av_len);
  170. output += bv->av_len;
  171. return output;
  172. }
  173. char *
  174. AMF_EncodeNumber(char *output, char *outend, double dVal)
  175. {
  176. if (output+1+8 > outend)
  177. return NULL;
  178. *output++ = AMF_NUMBER; /* type: Number */
  179. #if __FLOAT_WORD_ORDER == __BYTE_ORDER
  180. #if __BYTE_ORDER == __BIG_ENDIAN
  181. memcpy(output, &dVal, 8);
  182. #elif __BYTE_ORDER == __LITTLE_ENDIAN
  183. {
  184. unsigned char *ci, *co;
  185. ci = (unsigned char *)&dVal;
  186. co = (unsigned char *)output;
  187. co[0] = ci[7];
  188. co[1] = ci[6];
  189. co[2] = ci[5];
  190. co[3] = ci[4];
  191. co[4] = ci[3];
  192. co[5] = ci[2];
  193. co[6] = ci[1];
  194. co[7] = ci[0];
  195. }
  196. #endif
  197. #else
  198. #if __BYTE_ORDER == __LITTLE_ENDIAN /* __FLOAT_WORD_ORER == __BIG_ENDIAN */
  199. {
  200. unsigned char *ci, *co;
  201. ci = (unsigned char *)&dVal;
  202. co = (unsigned char *)output;
  203. co[0] = ci[3];
  204. co[1] = ci[2];
  205. co[2] = ci[1];
  206. co[3] = ci[0];
  207. co[4] = ci[7];
  208. co[5] = ci[6];
  209. co[6] = ci[5];
  210. co[7] = ci[4];
  211. }
  212. #else /* __BYTE_ORDER == __BIG_ENDIAN && __FLOAT_WORD_ORER == __LITTLE_ENDIAN */
  213. {
  214. unsigned char *ci, *co;
  215. ci = (unsigned char *)&dVal;
  216. co = (unsigned char *)output;
  217. co[0] = ci[4];
  218. co[1] = ci[5];
  219. co[2] = ci[6];
  220. co[3] = ci[7];
  221. co[4] = ci[0];
  222. co[5] = ci[1];
  223. co[6] = ci[2];
  224. co[7] = ci[3];
  225. }
  226. #endif
  227. #endif
  228. return output+8;
  229. }
  230. char *
  231. AMF_EncodeBoolean(char *output, char *outend, int bVal)
  232. {
  233. if (output+2 > outend)
  234. return NULL;
  235. *output++ = AMF_BOOLEAN;
  236. *output++ = bVal ? 0x01 : 0x00;
  237. return output;
  238. }
  239. char *
  240. AMF_EncodeNamedString(char *output, char *outend, const AVal *strName, const AVal *strValue)
  241. {
  242. if (output+2+strName->av_len > outend)
  243. return NULL;
  244. output = AMF_EncodeInt16(output, outend, strName->av_len);
  245. memcpy(output, strName->av_val, strName->av_len);
  246. output += strName->av_len;
  247. return AMF_EncodeString(output, outend, strValue);
  248. }
  249. char *
  250. AMF_EncodeNamedNumber(char *output, char *outend, const AVal *strName, double dVal)
  251. {
  252. if (output+2+strName->av_len > outend)
  253. return NULL;
  254. output = AMF_EncodeInt16(output, outend, strName->av_len);
  255. memcpy(output, strName->av_val, strName->av_len);
  256. output += strName->av_len;
  257. return AMF_EncodeNumber(output, outend, dVal);
  258. }
  259. char *
  260. AMF_EncodeNamedBoolean(char *output, char *outend, const AVal *strName, int bVal)
  261. {
  262. if (output+2+strName->av_len > outend)
  263. return NULL;
  264. output = AMF_EncodeInt16(output, outend, strName->av_len);
  265. memcpy(output, strName->av_val, strName->av_len);
  266. output += strName->av_len;
  267. return AMF_EncodeBoolean(output, outend, bVal);
  268. }
  269. void
  270. AMFProp_GetName(AMFObjectProperty *prop, AVal *name)
  271. {
  272. *name = prop->p_name;
  273. }
  274. void
  275. AMFProp_SetName(AMFObjectProperty *prop, AVal *name)
  276. {
  277. prop->p_name = *name;
  278. }
  279. AMFDataType
  280. AMFProp_GetType(AMFObjectProperty *prop)
  281. {
  282. return prop->p_type;
  283. }
  284. double
  285. AMFProp_GetNumber(AMFObjectProperty *prop)
  286. {
  287. return prop->p_vu.p_number;
  288. }
  289. int
  290. AMFProp_GetBoolean(AMFObjectProperty *prop)
  291. {
  292. return prop->p_vu.p_number != 0;
  293. }
  294. void
  295. AMFProp_GetString(AMFObjectProperty *prop, AVal *str)
  296. {
  297. if (prop->p_type == AMF_STRING)
  298. *str = prop->p_vu.p_aval;
  299. else
  300. *str = AV_empty;
  301. }
  302. void
  303. AMFProp_GetObject(AMFObjectProperty *prop, AMFObject *obj)
  304. {
  305. if (prop->p_type == AMF_OBJECT)
  306. *obj = prop->p_vu.p_object;
  307. else
  308. *obj = AMFObj_Invalid;
  309. }
  310. int
  311. AMFProp_IsValid(AMFObjectProperty *prop)
  312. {
  313. return prop->p_type != AMF_INVALID;
  314. }
  315. char *
  316. AMFProp_Encode(AMFObjectProperty *prop, char *pBuffer, char *pBufEnd)
  317. {
  318. if (prop->p_type == AMF_INVALID)
  319. return NULL;
  320. if (prop->p_type != AMF_NULL && pBuffer + prop->p_name.av_len + 2 + 1 >= pBufEnd)
  321. return NULL;
  322. if (prop->p_type != AMF_NULL && prop->p_name.av_len)
  323. {
  324. *pBuffer++ = prop->p_name.av_len >> 8;
  325. *pBuffer++ = prop->p_name.av_len & 0xff;
  326. memcpy(pBuffer, prop->p_name.av_val, prop->p_name.av_len);
  327. pBuffer += prop->p_name.av_len;
  328. }
  329. switch (prop->p_type)
  330. {
  331. case AMF_NUMBER:
  332. pBuffer = AMF_EncodeNumber(pBuffer, pBufEnd, prop->p_vu.p_number);
  333. break;
  334. case AMF_BOOLEAN:
  335. pBuffer = AMF_EncodeBoolean(pBuffer, pBufEnd, prop->p_vu.p_number != 0);
  336. break;
  337. case AMF_STRING:
  338. pBuffer = AMF_EncodeString(pBuffer, pBufEnd, &prop->p_vu.p_aval);
  339. break;
  340. case AMF_NULL:
  341. if (pBuffer+1 >= pBufEnd)
  342. return NULL;
  343. *pBuffer++ = AMF_NULL;
  344. break;
  345. case AMF_OBJECT:
  346. pBuffer = AMF_Encode(&prop->p_vu.p_object, pBuffer, pBufEnd);
  347. break;
  348. case AMF_ECMA_ARRAY:
  349. pBuffer = AMF_EncodeEcmaArray(&prop->p_vu.p_object, pBuffer, pBufEnd);
  350. break;
  351. case AMF_STRICT_ARRAY:
  352. pBuffer = AMF_EncodeArray(&prop->p_vu.p_object, pBuffer, pBufEnd);
  353. break;
  354. default:
  355. RTMP_Log(RTMP_LOGERROR, "%s, invalid type. %d", __FUNCTION__, prop->p_type);
  356. pBuffer = NULL;
  357. };
  358. return pBuffer;
  359. }
  360. #define AMF3_INTEGER_MAX 268435455
  361. #define AMF3_INTEGER_MIN -268435456
  362. int
  363. AMF3ReadInteger(const char *data, int32_t *valp)
  364. {
  365. int i = 0;
  366. int32_t val = 0;
  367. while (i <= 2)
  368. {
  369. /* handle first 3 bytes */
  370. if (data[i] & 0x80)
  371. {
  372. /* byte used */
  373. val <<= 7; /* shift up */
  374. val |= (data[i] & 0x7f); /* add bits */
  375. i++;
  376. }
  377. else
  378. {
  379. break;
  380. }
  381. }
  382. if (i > 2)
  383. {
  384. /* use 4th byte, all 8bits */
  385. val <<= 8;
  386. val |= data[3];
  387. /* range check */
  388. if (val > AMF3_INTEGER_MAX)
  389. val -= (1 << 29);
  390. }
  391. else
  392. {
  393. /* use 7bits of last unparsed byte (0xxxxxxx) */
  394. val <<= 7;
  395. val |= data[i];
  396. }
  397. *valp = val;
  398. return i > 2 ? 4 : i + 1;
  399. }
  400. int
  401. AMF3ReadString(const char *data, AVal *str)
  402. {
  403. int32_t ref = 0;
  404. int len;
  405. assert(str != 0);
  406. len = AMF3ReadInteger(data, &ref);
  407. data += len;
  408. if ((ref & 0x1) == 0)
  409. {
  410. /* reference: 0xxx */
  411. uint32_t refIndex = (ref >> 1);
  412. RTMP_Log(RTMP_LOGDEBUG,
  413. "%s, string reference, index: %d, not supported, ignoring!",
  414. __FUNCTION__, refIndex);
  415. str->av_val = NULL;
  416. str->av_len = 0;
  417. return len;
  418. }
  419. else
  420. {
  421. uint32_t nSize = (ref >> 1);
  422. str->av_val = (char *)data;
  423. str->av_len = nSize;
  424. return len + nSize;
  425. }
  426. return len;
  427. }
  428. int
  429. AMF3Prop_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
  430. int bDecodeName)
  431. {
  432. int nOriginalSize = nSize;
  433. AMF3DataType type;
  434. prop->p_name.av_len = 0;
  435. prop->p_name.av_val = NULL;
  436. if (nSize == 0 || !pBuffer)
  437. {
  438. RTMP_Log(RTMP_LOGDEBUG, "empty buffer/no buffer pointer!");
  439. return -1;
  440. }
  441. /* decode name */
  442. if (bDecodeName)
  443. {
  444. AVal name = AV_empty;
  445. int nRes = AMF3ReadString(pBuffer, &name);
  446. if (name.av_len <= 0)
  447. return nRes;
  448. nSize -= nRes;
  449. if (nSize <= 0)
  450. return -1;
  451. prop->p_name = name;
  452. pBuffer += nRes;
  453. }
  454. /* decode */
  455. type = *pBuffer++;
  456. nSize--;
  457. switch (type)
  458. {
  459. case AMF3_UNDEFINED:
  460. case AMF3_NULL:
  461. prop->p_type = AMF_NULL;
  462. break;
  463. case AMF3_FALSE:
  464. prop->p_type = AMF_BOOLEAN;
  465. prop->p_vu.p_number = 0.0;
  466. break;
  467. case AMF3_TRUE:
  468. prop->p_type = AMF_BOOLEAN;
  469. prop->p_vu.p_number = 1.0;
  470. break;
  471. case AMF3_INTEGER:
  472. {
  473. int32_t res = 0;
  474. int len = AMF3ReadInteger(pBuffer, &res);
  475. prop->p_vu.p_number = (double)res;
  476. prop->p_type = AMF_NUMBER;
  477. nSize -= len;
  478. break;
  479. }
  480. case AMF3_DOUBLE:
  481. if (nSize < 8)
  482. return -1;
  483. prop->p_vu.p_number = AMF_DecodeNumber(pBuffer);
  484. prop->p_type = AMF_NUMBER;
  485. nSize -= 8;
  486. break;
  487. case AMF3_STRING:
  488. case AMF3_XML_DOC:
  489. case AMF3_XML:
  490. {
  491. int len = AMF3ReadString(pBuffer, &prop->p_vu.p_aval);
  492. prop->p_type = AMF_STRING;
  493. nSize -= len;
  494. break;
  495. }
  496. case AMF3_DATE:
  497. {
  498. int32_t res = 0;
  499. int len = AMF3ReadInteger(pBuffer, &res);
  500. nSize -= len;
  501. pBuffer += len;
  502. if ((res & 0x1) == 0)
  503. {
  504. /* reference */
  505. uint32_t nIndex = (res >> 1);
  506. RTMP_Log(RTMP_LOGDEBUG, "AMF3_DATE reference: %d, not supported!", nIndex);
  507. }
  508. else
  509. {
  510. if (nSize < 8)
  511. return -1;
  512. prop->p_vu.p_number = AMF_DecodeNumber(pBuffer);
  513. nSize -= 8;
  514. prop->p_type = AMF_NUMBER;
  515. }
  516. break;
  517. }
  518. case AMF3_OBJECT:
  519. {
  520. int nRes = AMF3_Decode(&prop->p_vu.p_object, pBuffer, nSize, TRUE);
  521. if (nRes == -1)
  522. return -1;
  523. nSize -= nRes;
  524. prop->p_type = AMF_OBJECT;
  525. break;
  526. }
  527. case AMF3_ARRAY:
  528. case AMF3_BYTE_ARRAY:
  529. default:
  530. RTMP_Log(RTMP_LOGDEBUG, "%s - AMF3 unknown/unsupported datatype 0x%02x, @%p",
  531. __FUNCTION__, (unsigned char)(*pBuffer), pBuffer);
  532. return -1;
  533. }
  534. if (nSize < 0)
  535. return -1;
  536. return nOriginalSize - nSize;
  537. }
  538. int
  539. AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
  540. int bDecodeName)
  541. {
  542. int nOriginalSize = nSize;
  543. int nRes;
  544. prop->p_name.av_len = 0;
  545. prop->p_name.av_val = NULL;
  546. if (nSize == 0 || !pBuffer)
  547. {
  548. RTMP_Log(RTMP_LOGDEBUG, "%s: Empty buffer/no buffer pointer!", __FUNCTION__);
  549. return -1;
  550. }
  551. if (bDecodeName && nSize < 4)
  552. {
  553. /* at least name (length + at least 1 byte) and 1 byte of data */
  554. RTMP_Log(RTMP_LOGDEBUG,
  555. "%s: Not enough data for decoding with name, less than 4 bytes!",
  556. __FUNCTION__);
  557. return -1;
  558. }
  559. if (bDecodeName)
  560. {
  561. unsigned short nNameSize = AMF_DecodeInt16(pBuffer);
  562. if (nNameSize > nSize - 2)
  563. {
  564. RTMP_Log(RTMP_LOGDEBUG,
  565. "%s: Name size out of range: namesize (%d) > len (%d) - 2",
  566. __FUNCTION__, nNameSize, nSize);
  567. return -1;
  568. }
  569. AMF_DecodeString(pBuffer, &prop->p_name);
  570. nSize -= 2 + nNameSize;
  571. pBuffer += 2 + nNameSize;
  572. }
  573. if (nSize == 0)
  574. {
  575. return -1;
  576. }
  577. nSize--;
  578. prop->p_type = *pBuffer++;
  579. switch (prop->p_type)
  580. {
  581. case AMF_NUMBER:
  582. if (nSize < 8)
  583. return -1;
  584. prop->p_vu.p_number = AMF_DecodeNumber(pBuffer);
  585. nSize -= 8;
  586. break;
  587. case AMF_BOOLEAN:
  588. if (nSize < 1)
  589. return -1;
  590. prop->p_vu.p_number = (double)AMF_DecodeBoolean(pBuffer);
  591. nSize--;
  592. break;
  593. case AMF_STRING:
  594. {
  595. unsigned short nStringSize = AMF_DecodeInt16(pBuffer);
  596. if (nSize < (long)nStringSize + 2)
  597. return -1;
  598. AMF_DecodeString(pBuffer, &prop->p_vu.p_aval);
  599. nSize -= (2 + nStringSize);
  600. break;
  601. }
  602. case AMF_OBJECT:
  603. {
  604. int nRes = AMF_Decode(&prop->p_vu.p_object, pBuffer, nSize, TRUE);
  605. if (nRes == -1)
  606. return -1;
  607. nSize -= nRes;
  608. break;
  609. }
  610. case AMF_MOVIECLIP:
  611. {
  612. RTMP_Log(RTMP_LOGERROR, "AMF_MOVIECLIP reserved!");
  613. return -1;
  614. break;
  615. }
  616. case AMF_NULL:
  617. case AMF_UNDEFINED:
  618. case AMF_UNSUPPORTED:
  619. prop->p_type = AMF_NULL;
  620. break;
  621. case AMF_REFERENCE:
  622. {
  623. RTMP_Log(RTMP_LOGERROR, "AMF_REFERENCE not supported!");
  624. return -1;
  625. break;
  626. }
  627. case AMF_ECMA_ARRAY:
  628. {
  629. nSize -= 4;
  630. /* next comes the rest, mixed array has a final 0x000009 mark and names, so its an object */
  631. nRes = AMF_Decode(&prop->p_vu.p_object, pBuffer + 4, nSize, TRUE);
  632. if (nRes == -1)
  633. return -1;
  634. nSize -= nRes;
  635. break;
  636. }
  637. case AMF_OBJECT_END:
  638. {
  639. return -1;
  640. break;
  641. }
  642. case AMF_STRICT_ARRAY:
  643. {
  644. unsigned int nArrayLen = AMF_DecodeInt32(pBuffer);
  645. nSize -= 4;
  646. nRes = AMF_DecodeArray(&prop->p_vu.p_object, pBuffer + 4, nSize,
  647. nArrayLen, FALSE);
  648. if (nRes == -1)
  649. return -1;
  650. nSize -= nRes;
  651. break;
  652. }
  653. case AMF_DATE:
  654. {
  655. RTMP_Log(RTMP_LOGDEBUG, "AMF_DATE");
  656. if (nSize < 10)
  657. return -1;
  658. prop->p_vu.p_number = AMF_DecodeNumber(pBuffer);
  659. prop->p_UTCoffset = AMF_DecodeInt16(pBuffer + 8);
  660. nSize -= 10;
  661. break;
  662. }
  663. case AMF_LONG_STRING:
  664. case AMF_XML_DOC:
  665. {
  666. unsigned int nStringSize = AMF_DecodeInt32(pBuffer);
  667. if (nSize < (long)nStringSize + 4)
  668. return -1;
  669. AMF_DecodeLongString(pBuffer, &prop->p_vu.p_aval);
  670. nSize -= (4 + nStringSize);
  671. if (prop->p_type == AMF_LONG_STRING)
  672. prop->p_type = AMF_STRING;
  673. break;
  674. }
  675. case AMF_RECORDSET:
  676. {
  677. RTMP_Log(RTMP_LOGERROR, "AMF_RECORDSET reserved!");
  678. return -1;
  679. break;
  680. }
  681. case AMF_TYPED_OBJECT:
  682. {
  683. RTMP_Log(RTMP_LOGERROR, "AMF_TYPED_OBJECT not supported!");
  684. return -1;
  685. break;
  686. }
  687. case AMF_AVMPLUS:
  688. {
  689. int nRes = AMF3_Decode(&prop->p_vu.p_object, pBuffer, nSize, TRUE);
  690. if (nRes == -1)
  691. return -1;
  692. nSize -= nRes;
  693. prop->p_type = AMF_OBJECT;
  694. break;
  695. }
  696. default:
  697. RTMP_Log(RTMP_LOGDEBUG, "%s - unknown datatype 0x%02x, @%p", __FUNCTION__,
  698. prop->p_type, pBuffer - 1);
  699. return -1;
  700. }
  701. return nOriginalSize - nSize;
  702. }
  703. void
  704. AMFProp_Dump(AMFObjectProperty *prop)
  705. {
  706. char strRes[256];
  707. char str[256];
  708. AVal name;
  709. if (prop->p_type == AMF_INVALID)
  710. {
  711. RTMP_Log(RTMP_LOGDEBUG, "Property: INVALID");
  712. return;
  713. }
  714. if (prop->p_type == AMF_NULL)
  715. {
  716. RTMP_Log(RTMP_LOGDEBUG, "Property: NULL");
  717. return;
  718. }
  719. if (prop->p_name.av_len)
  720. {
  721. name = prop->p_name;
  722. }
  723. else
  724. {
  725. name.av_val = "no-name.";
  726. name.av_len = sizeof("no-name.") - 1;
  727. }
  728. if (name.av_len > 18)
  729. name.av_len = 18;
  730. snprintf(strRes, sizeof(strRes), "Name: %18.*s, ", name.av_len, name.av_val);
  731. if (prop->p_type == AMF_OBJECT)
  732. {
  733. RTMP_Log(RTMP_LOGDEBUG, "Property: <%sOBJECT>", strRes);
  734. AMF_Dump(&prop->p_vu.p_object);
  735. return;
  736. }
  737. else if (prop->p_type == AMF_ECMA_ARRAY)
  738. {
  739. RTMP_Log(RTMP_LOGDEBUG, "Property: <%sECMA_ARRAY>", strRes);
  740. AMF_Dump(&prop->p_vu.p_object);
  741. return;
  742. }
  743. else if (prop->p_type == AMF_STRICT_ARRAY)
  744. {
  745. RTMP_Log(RTMP_LOGDEBUG, "Property: <%sSTRICT_ARRAY>", strRes);
  746. AMF_Dump(&prop->p_vu.p_object);
  747. return;
  748. }
  749. switch (prop->p_type)
  750. {
  751. case AMF_NUMBER:
  752. snprintf(str, sizeof(str), "NUMBER:\t%.2f", prop->p_vu.p_number);
  753. break;
  754. case AMF_BOOLEAN:
  755. snprintf(str, sizeof(str), "BOOLEAN:\t%s",
  756. prop->p_vu.p_number != 0.0 ? "TRUE" : "FALSE");
  757. break;
  758. case AMF_STRING:
  759. snprintf(str, sizeof(str), "STRING:\t%.*s", prop->p_vu.p_aval.av_len,
  760. prop->p_vu.p_aval.av_val);
  761. break;
  762. case AMF_DATE:
  763. snprintf(str, sizeof(str), "DATE:\ttimestamp: %.2f, UTC offset: %d",
  764. prop->p_vu.p_number, prop->p_UTCoffset);
  765. break;
  766. default:
  767. snprintf(str, sizeof(str), "INVALID TYPE 0x%02x", (unsigned char)prop->p_type);
  768. }
  769. RTMP_Log(RTMP_LOGDEBUG, "Property: <%s%s>", strRes, str);
  770. }
  771. void
  772. AMFProp_Reset(AMFObjectProperty *prop)
  773. {
  774. if (prop->p_type == AMF_OBJECT || prop->p_type == AMF_ECMA_ARRAY || prop->p_type == AMF_STRICT_ARRAY)
  775. AMF_Reset(&prop->p_vu.p_object);
  776. else
  777. {
  778. prop->p_vu.p_aval.av_len = 0;
  779. prop->p_vu.p_aval.av_val = NULL;
  780. }
  781. prop->p_type = AMF_INVALID;
  782. }
  783. /* AMFObject */
  784. char *
  785. AMF_Encode(AMFObject *obj, char *pBuffer, char *pBufEnd)
  786. {
  787. int i;
  788. if (pBuffer+4 >= pBufEnd)
  789. return NULL;
  790. *pBuffer++ = AMF_OBJECT;
  791. for (i = 0; i < obj->o_num; i++)
  792. {
  793. char *res = AMFProp_Encode(&obj->o_props[i], pBuffer, pBufEnd);
  794. if (res == NULL)
  795. {
  796. RTMP_Log(RTMP_LOGERROR, "AMF_Encode - failed to encode property in index %d",
  797. i);
  798. break;
  799. }
  800. else
  801. {
  802. pBuffer = res;
  803. }
  804. }
  805. if (pBuffer + 3 >= pBufEnd)
  806. return NULL; /* no room for the end marker */
  807. pBuffer = AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END);
  808. return pBuffer;
  809. }
  810. char *
  811. AMF_EncodeEcmaArray(AMFObject *obj, char *pBuffer, char *pBufEnd)
  812. {
  813. int i;
  814. if (pBuffer+4 >= pBufEnd)
  815. return NULL;
  816. *pBuffer++ = AMF_ECMA_ARRAY;
  817. pBuffer = AMF_EncodeInt32(pBuffer, pBufEnd, obj->o_num);
  818. for (i = 0; i < obj->o_num; i++)
  819. {
  820. char *res = AMFProp_Encode(&obj->o_props[i], pBuffer, pBufEnd);
  821. if (res == NULL)
  822. {
  823. RTMP_Log(RTMP_LOGERROR, "AMF_Encode - failed to encode property in index %d",
  824. i);
  825. break;
  826. }
  827. else
  828. {
  829. pBuffer = res;
  830. }
  831. }
  832. if (pBuffer + 3 >= pBufEnd)
  833. return NULL; /* no room for the end marker */
  834. pBuffer = AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END);
  835. return pBuffer;
  836. }
  837. char *
  838. AMF_EncodeArray(AMFObject *obj, char *pBuffer, char *pBufEnd)
  839. {
  840. int i;
  841. if (pBuffer+4 >= pBufEnd)
  842. return NULL;
  843. *pBuffer++ = AMF_STRICT_ARRAY;
  844. pBuffer = AMF_EncodeInt32(pBuffer, pBufEnd, obj->o_num);
  845. for (i = 0; i < obj->o_num; i++)
  846. {
  847. char *res = AMFProp_Encode(&obj->o_props[i], pBuffer, pBufEnd);
  848. if (res == NULL)
  849. {
  850. RTMP_Log(RTMP_LOGERROR, "AMF_Encode - failed to encode property in index %d",
  851. i);
  852. break;
  853. }
  854. else
  855. {
  856. pBuffer = res;
  857. }
  858. }
  859. //if (pBuffer + 3 >= pBufEnd)
  860. // return NULL; /* no room for the end marker */
  861. //pBuffer = AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END);
  862. return pBuffer;
  863. }
  864. int
  865. AMF_DecodeArray(AMFObject *obj, const char *pBuffer, int nSize,
  866. int nArrayLen, int bDecodeName)
  867. {
  868. int nOriginalSize = nSize;
  869. int bError = FALSE;
  870. obj->o_num = 0;
  871. obj->o_props = NULL;
  872. while (nArrayLen > 0)
  873. {
  874. AMFObjectProperty prop;
  875. int nRes;
  876. nArrayLen--;
  877. if (nSize <= 0)
  878. {
  879. bError = TRUE;
  880. break;
  881. }
  882. nRes = AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName);
  883. if (nRes == -1)
  884. {
  885. bError = TRUE;
  886. break;
  887. }
  888. else
  889. {
  890. nSize -= nRes;
  891. pBuffer += nRes;
  892. AMF_AddProp(obj, &prop);
  893. }
  894. }
  895. if (bError)
  896. return -1;
  897. return nOriginalSize - nSize;
  898. }
  899. int
  900. AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
  901. {
  902. int nOriginalSize = nSize;
  903. int32_t ref;
  904. int len;
  905. obj->o_num = 0;
  906. obj->o_props = NULL;
  907. if (bAMFData)
  908. {
  909. if (*pBuffer != AMF3_OBJECT)
  910. RTMP_Log(RTMP_LOGERROR,
  911. "AMF3 Object encapsulated in AMF stream does not start with AMF3_OBJECT!");
  912. pBuffer++;
  913. nSize--;
  914. }
  915. ref = 0;
  916. len = AMF3ReadInteger(pBuffer, &ref);
  917. pBuffer += len;
  918. nSize -= len;
  919. if ((ref & 1) == 0)
  920. {
  921. /* object reference, 0xxx */
  922. uint32_t objectIndex = (ref >> 1);
  923. RTMP_Log(RTMP_LOGDEBUG, "Object reference, index: %d", objectIndex);
  924. }
  925. else /* object instance */
  926. {
  927. int32_t classRef = (ref >> 1);
  928. AMF3ClassDef cd = { {0, 0}
  929. };
  930. AMFObjectProperty prop;
  931. if ((classRef & 0x1) == 0)
  932. {
  933. /* class reference */
  934. uint32_t classIndex = (classRef >> 1);
  935. RTMP_Log(RTMP_LOGDEBUG, "Class reference: %d", classIndex);
  936. }
  937. else
  938. {
  939. int32_t classExtRef = (classRef >> 1);
  940. int i, cdnum;
  941. cd.cd_externalizable = (classExtRef & 0x1) == 1;
  942. cd.cd_dynamic = ((classExtRef >> 1) & 0x1) == 1;
  943. cdnum = classExtRef >> 2;
  944. /* class name */
  945. len = AMF3ReadString(pBuffer, &cd.cd_name);
  946. nSize -= len;
  947. pBuffer += len;
  948. /*std::string str = className; */
  949. RTMP_Log(RTMP_LOGDEBUG,
  950. "Class name: %s, externalizable: %d, dynamic: %d, classMembers: %d",
  951. cd.cd_name.av_val, cd.cd_externalizable, cd.cd_dynamic,
  952. cd.cd_num);
  953. for (i = 0; i < cdnum; i++)
  954. {
  955. AVal memberName = AV_empty;
  956. if (nSize <= 0)
  957. {
  958. invalid:
  959. RTMP_Log(RTMP_LOGDEBUG, "%s, invalid class encoding!",
  960. __FUNCTION__);
  961. return nOriginalSize;
  962. }
  963. len = AMF3ReadString(pBuffer, &memberName);
  964. RTMP_Log(RTMP_LOGDEBUG, "Member: %s", memberName.av_val);
  965. AMF3CD_AddProp(&cd, &memberName);
  966. nSize -= len;
  967. pBuffer += len;
  968. }
  969. }
  970. /* add as referencable object */
  971. if (cd.cd_externalizable)
  972. {
  973. int nRes;
  974. AVal name = AVC("DEFAULT_ATTRIBUTE");
  975. RTMP_Log(RTMP_LOGDEBUG, "Externalizable, TODO check");
  976. nRes = AMF3Prop_Decode(&prop, pBuffer, nSize, FALSE);
  977. if (nRes == -1)
  978. RTMP_Log(RTMP_LOGDEBUG, "%s, failed to decode AMF3 property!",
  979. __FUNCTION__);
  980. else
  981. {
  982. nSize -= nRes;
  983. pBuffer += nRes;
  984. }
  985. AMFProp_SetName(&prop, &name);
  986. AMF_AddProp(obj, &prop);
  987. }
  988. else
  989. {
  990. int nRes, i;
  991. for (i = 0; i < cd.cd_num; i++) /* non-dynamic */
  992. {
  993. if (nSize <= 0)
  994. goto invalid;
  995. nRes = AMF3Prop_Decode(&prop, pBuffer, nSize, FALSE);
  996. if (nRes == -1)
  997. RTMP_Log(RTMP_LOGDEBUG, "%s, failed to decode AMF3 property!",
  998. __FUNCTION__);
  999. AMFProp_SetName(&prop, AMF3CD_GetProp(&cd, i));
  1000. AMF_AddProp(obj, &prop);
  1001. pBuffer += nRes;
  1002. nSize -= nRes;
  1003. }
  1004. if (cd.cd_dynamic)
  1005. {
  1006. int len = 0;
  1007. do
  1008. {
  1009. if (nSize <= 0)
  1010. goto invalid;
  1011. nRes = AMF3Prop_Decode(&prop, pBuffer, nSize, TRUE);
  1012. AMF_AddProp(obj, &prop);
  1013. pBuffer += nRes;
  1014. nSize -= nRes;
  1015. len = prop.p_name.av_len;
  1016. }
  1017. while (len > 0);
  1018. }
  1019. }
  1020. RTMP_Log(RTMP_LOGDEBUG, "class object!");
  1021. }
  1022. return nOriginalSize - nSize;
  1023. }
  1024. int
  1025. AMF_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bDecodeName)
  1026. {
  1027. int nOriginalSize = nSize;
  1028. int bError = FALSE; /* if there is an error while decoding - try to at least find the end mark AMF_OBJECT_END */
  1029. obj->o_num = 0;
  1030. obj->o_props = NULL;
  1031. while (nSize > 0)
  1032. {
  1033. AMFObjectProperty prop;
  1034. int nRes;
  1035. if (nSize >=3 && AMF_DecodeInt24(pBuffer) == AMF_OBJECT_END)
  1036. {
  1037. nSize -= 3;
  1038. bError = FALSE;
  1039. break;
  1040. }
  1041. if (bError)
  1042. {
  1043. RTMP_Log(RTMP_LOGERROR,
  1044. "DECODING ERROR, IGNORING BYTES UNTIL NEXT KNOWN PATTERN!");
  1045. nSize--;
  1046. pBuffer++;
  1047. continue;
  1048. }
  1049. nRes = AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName);
  1050. if (nRes == -1)
  1051. {
  1052. bError = TRUE;
  1053. break;
  1054. }
  1055. else
  1056. {
  1057. nSize -= nRes;
  1058. if (nSize < 0)
  1059. {
  1060. bError = TRUE;
  1061. break;
  1062. }
  1063. pBuffer += nRes;
  1064. AMF_AddProp(obj, &prop);
  1065. }
  1066. }
  1067. if (bError)
  1068. return -1;
  1069. return nOriginalSize - nSize;
  1070. }
  1071. void
  1072. AMF_AddProp(AMFObject *obj, const AMFObjectProperty *prop)
  1073. {
  1074. if (!(obj->o_num & 0x0f))
  1075. obj->o_props =
  1076. realloc(obj->o_props, (obj->o_num + 16) * sizeof(AMFObjectProperty));
  1077. memcpy(&obj->o_props[obj->o_num++], prop, sizeof(AMFObjectProperty));
  1078. }
  1079. int
  1080. AMF_CountProp(AMFObject *obj)
  1081. {
  1082. return obj->o_num;
  1083. }
  1084. AMFObjectProperty *
  1085. AMF_GetProp(AMFObject *obj, const AVal *name, int nIndex)
  1086. {
  1087. if (nIndex >= 0)
  1088. {
  1089. if (nIndex < obj->o_num)
  1090. return &obj->o_props[nIndex];
  1091. }
  1092. else
  1093. {
  1094. int n;
  1095. for (n = 0; n < obj->o_num; n++)
  1096. {
  1097. if (AVMATCH(&obj->o_props[n].p_name, name))
  1098. return &obj->o_props[n];
  1099. }
  1100. }
  1101. return (AMFObjectProperty *)&AMFProp_Invalid;
  1102. }
  1103. void
  1104. AMF_Dump(AMFObject *obj)
  1105. {
  1106. int n;
  1107. RTMP_Log(RTMP_LOGDEBUG, "(object begin)");
  1108. for (n = 0; n < obj->o_num; n++)
  1109. {
  1110. AMFProp_Dump(&obj->o_props[n]);
  1111. }
  1112. RTMP_Log(RTMP_LOGDEBUG, "(object end)");
  1113. }
  1114. void
  1115. AMF_Reset(AMFObject *obj)
  1116. {
  1117. int n;
  1118. for (n = 0; n < obj->o_num; n++)
  1119. {
  1120. AMFProp_Reset(&obj->o_props[n]);
  1121. }
  1122. free(obj->o_props);
  1123. obj->o_props = NULL;
  1124. obj->o_num = 0;
  1125. }
  1126. /* AMF3ClassDefinition */
  1127. void
  1128. AMF3CD_AddProp(AMF3ClassDef *cd, AVal *prop)
  1129. {
  1130. if (!(cd->cd_num & 0x0f))
  1131. cd->cd_props = realloc(cd->cd_props, (cd->cd_num + 16) * sizeof(AVal));
  1132. cd->cd_props[cd->cd_num++] = *prop;
  1133. }
  1134. AVal *
  1135. AMF3CD_GetProp(AMF3ClassDef *cd, int nIndex)
  1136. {
  1137. if (nIndex >= cd->cd_num)
  1138. return (AVal *)&AV_empty;
  1139. return &cd->cd_props[nIndex];
  1140. }