PageRenderTime 30ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/2.0/Source/ExtSupport/PHP4/InternalFileFunctions.cpp

#
C++ | 468 lines | 306 code | 85 blank | 77 comment | 91 complexity | c5e43e649b880496d02179aa6f1070af MD5 | raw file
Possible License(s): CPL-1.0, GPL-2.0, CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, Apache-2.0
  1. //
  2. // ExtSupport.PHP4 - substitute for php4ts.dll
  3. //
  4. // InternalFileFunctions.cpp
  5. // - contains definitions of "zif" exported file functions
  6. //
  7. #include "stdafx.h"
  8. #include "InternalFileFunctions.h"
  9. #include "Streams.h"
  10. #include "Parameters.h"
  11. #include "Memory.h"
  12. #include "Errors.h"
  13. #include "Resources.h"
  14. #include "Variables.h"
  15. #include "Strings.h"
  16. #include "TsrmLs.h"
  17. #include "Streams.h"
  18. #include <stdio.h>
  19. #include <io.h>
  20. #pragma unmanaged
  21. // copied from file.c and beautified
  22. /* {{{ proto bool fclose(resource fp)
  23. Close an open file pointer */
  24. ZEND_API ZEND_FUNCTION(fclose)
  25. {
  26. zval **arg1;
  27. php_stream *stream;
  28. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) WRONG_PARAM_COUNT;
  29. php_stream_from_zval(stream, arg1);
  30. if (!stream->is_persistent) zend_list_delete(stream->rsrc_id);
  31. else php_stream_pclose(stream);
  32. RETURN_TRUE;
  33. }
  34. // copied from file.c and beautified
  35. /* {{{ proto bool feof(resource fp)
  36. Test for end-of-file on a file pointer */
  37. ZEND_API ZEND_FUNCTION(feof)
  38. {
  39. zval **arg1;
  40. php_stream *stream;
  41. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) WRONG_PARAM_COUNT;
  42. php_stream_from_zval(stream, arg1);
  43. if (php_stream_eof(stream))
  44. {
  45. RETURN_TRUE;
  46. }
  47. else RETURN_FALSE;
  48. }
  49. /* }}} */
  50. #pragma managed
  51. // copied from file.c and beautified
  52. /* {{{ proto string fgets(resource fp[, int length])
  53. Get a line from file pointer */
  54. ZEND_API ZEND_FUNCTION(fgets)
  55. {
  56. zval **arg1, **arg2;
  57. int len = 1024;
  58. char *buf = NULL;
  59. int argc = ZEND_NUM_ARGS();
  60. size_t line_len = 0;
  61. php_stream *stream;
  62. if (argc<1 || argc>2 || zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) WRONG_PARAM_COUNT;
  63. php_stream_from_zval(stream, arg1);
  64. if (argc == 1)
  65. {
  66. /* ask streams to give us a buffer of an appropriate size */
  67. buf = php_stream_get_line(stream, NULL, 0, &line_len);
  68. if (buf == NULL) goto exit_failed;
  69. }
  70. else if (argc > 1)
  71. {
  72. convert_to_long_ex(arg2);
  73. len = Z_LVAL_PP(arg2);
  74. if (len < 0)
  75. {
  76. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative");
  77. RETURN_FALSE;
  78. }
  79. buf = (char *)ecalloc(len + 1, sizeof(char));
  80. if (php_stream_get_line(stream, buf, len, &line_len) == NULL) goto exit_failed;
  81. }
  82. //if (PG(magic_quotes_runtime))
  83. if (PHP::Core::ScriptContext::CurrentContext->Config->Variables->QuoteRuntimeVariables)
  84. {
  85. Z_STRVAL_P(return_value) = php_addslashes(buf, line_len, &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
  86. Z_TYPE_P(return_value) = IS_STRING;
  87. }
  88. //else
  89. //{
  90. // ZVAL_STRINGL(return_value, buf, line_len, 0);
  91. // /* resize buffer if it's much larger than the result.
  92. // * Only needed if the user requested a buffer size. */
  93. // if (argc > 1 && Z_STRLEN_P(return_value) < len / 2)
  94. // {
  95. // Z_STRVAL_P(return_value) = (char *)erealloc(buf, line_len + 1);
  96. // }
  97. //}
  98. return;
  99. exit_failed:
  100. RETVAL_FALSE;
  101. if (buf) efree(buf);
  102. }
  103. /* }}} */
  104. #pragma unmanaged
  105. // copied from file.c and beautified
  106. /* {{{ proto string fgetc(resource fp)
  107. Get a character from file pointer */
  108. ZEND_API ZEND_FUNCTION(fgetc)
  109. {
  110. zval **arg1;
  111. char *buf;
  112. int result;
  113. php_stream *stream;
  114. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) WRONG_PARAM_COUNT;
  115. php_stream_from_zval(stream, arg1);
  116. buf = (char *)safe_emalloc(2, sizeof(char), 0);
  117. result = php_stream_getc(stream);
  118. if (result == EOF)
  119. {
  120. efree(buf);
  121. RETVAL_FALSE;
  122. }
  123. else
  124. {
  125. buf[0] = result;
  126. buf[1] = '\0';
  127. RETURN_STRINGL(buf, 1, 0);
  128. }
  129. }
  130. /* }}} */
  131. // copied from file.c and beautified
  132. /* {{{ proto string fgetss(resource fp [, int length, string allowable_tags])
  133. Get a line from file pointer and strip HTML tags */
  134. ZEND_API ZEND_FUNCTION(fgetss)
  135. {
  136. zval **fd, **bytes = NULL, **allow = NULL;
  137. size_t len = 0;
  138. size_t actual_len, retval_len;
  139. char *buf = NULL, *retval;
  140. php_stream *stream;
  141. char *allowed_tags=NULL;
  142. int allowed_tags_len=0;
  143. switch (ZEND_NUM_ARGS())
  144. {
  145. case 1:
  146. if (zend_get_parameters_ex(1, &fd) == FAILURE) RETURN_FALSE;
  147. break;
  148. case 2:
  149. if (zend_get_parameters_ex(2, &fd, &bytes) == FAILURE) RETURN_FALSE;
  150. break;
  151. case 3:
  152. if (zend_get_parameters_ex(3, &fd, &bytes, &allow) == FAILURE) RETURN_FALSE;
  153. convert_to_string_ex(allow);
  154. allowed_tags = Z_STRVAL_PP(allow);
  155. allowed_tags_len = Z_STRLEN_PP(allow);
  156. break;
  157. default:
  158. WRONG_PARAM_COUNT;
  159. /* NOTREACHED */
  160. break;
  161. }
  162. php_stream_from_zval(stream, fd);
  163. if (bytes != NULL)
  164. {
  165. convert_to_long_ex(bytes);
  166. if (Z_LVAL_PP(bytes) < 0)
  167. {
  168. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative");
  169. RETURN_FALSE;
  170. }
  171. len = (size_t) Z_LVAL_PP(bytes);
  172. buf = (char *)safe_emalloc(sizeof(char), (len + 1), 0);
  173. /*needed because recv doesnt set null char at end*/
  174. memset(buf, 0, len + 1);
  175. }
  176. if ((retval = php_stream_get_line(stream, buf, len, &actual_len)) == NULL)
  177. {
  178. if (buf != NULL) efree(buf);
  179. RETURN_FALSE;
  180. }
  181. retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len);
  182. RETURN_STRINGL(retval, retval_len, 0);
  183. }
  184. /* }}} */
  185. #pragma managed
  186. // copied from file.c and beautified
  187. /* {{{ proto int fwrite(resource fp, string str [, int length])
  188. Binary-safe file write */
  189. ZEND_API ZEND_FUNCTION(fwrite)
  190. {
  191. zval **arg1, **arg2, **arg3=NULL;
  192. int ret;
  193. int num_bytes;
  194. char *buffer = NULL;
  195. php_stream *stream;
  196. switch (ZEND_NUM_ARGS())
  197. {
  198. case 2:
  199. if (zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) RETURN_FALSE;
  200. convert_to_string_ex(arg2);
  201. num_bytes = Z_STRLEN_PP(arg2);
  202. break;
  203. case 3:
  204. if (zend_get_parameters_ex(3, &arg1, &arg2, &arg3) == FAILURE) RETURN_FALSE;
  205. convert_to_string_ex(arg2);
  206. convert_to_long_ex(arg3);
  207. num_bytes = MIN(Z_LVAL_PP(arg3), Z_STRLEN_PP(arg2));
  208. break;
  209. default:
  210. WRONG_PARAM_COUNT;
  211. /* NOTREACHED */
  212. break;
  213. }
  214. php_stream_from_zval(stream, arg1);
  215. //if (!arg3 && PG(magic_quotes_runtime))
  216. if (!arg3 && PHP::Core::ScriptContext::CurrentContext->Config->Variables->QuoteRuntimeVariables)
  217. {
  218. buffer = estrndup(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2));
  219. php_stripslashes(buffer, &num_bytes TSRMLS_CC);
  220. }
  221. ret = php_stream_write(stream, buffer ? buffer : Z_STRVAL_PP(arg2), num_bytes);
  222. if (buffer) efree(buffer);
  223. RETURN_LONG(ret);
  224. }
  225. /* }}} */
  226. #pragma unmanaged
  227. // copied from file.c and beautified
  228. /* {{{ proto bool fflush(resource fp)
  229. Flushes output */
  230. ZEND_API ZEND_FUNCTION(fflush)
  231. {
  232. zval **arg1;
  233. int ret;
  234. php_stream *stream;
  235. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) WRONG_PARAM_COUNT;
  236. php_stream_from_zval(stream, arg1);
  237. ret = php_stream_flush(stream);
  238. if (ret) RETURN_FALSE;
  239. RETURN_TRUE;
  240. }
  241. /* }}} */
  242. // copied from file.c and beautified
  243. /* {{{ proto bool rewind(resource fp)
  244. Rewind the position of a file pointer */
  245. ZEND_API ZEND_FUNCTION(rewind)
  246. {
  247. zval **arg1;
  248. php_stream *stream;
  249. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) WRONG_PARAM_COUNT;
  250. php_stream_from_zval(stream, arg1);
  251. if (-1 == php_stream_rewind(stream)) RETURN_FALSE;
  252. RETURN_TRUE;
  253. }
  254. /* }}} */
  255. // copied from file.c and beautified
  256. /* {{{ proto int ftell(resource fp)
  257. Get file pointer's read/write position */
  258. ZEND_API ZEND_FUNCTION(ftell)
  259. {
  260. zval **arg1;
  261. long ret;
  262. php_stream *stream;
  263. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) WRONG_PARAM_COUNT;
  264. php_stream_from_zval(stream, arg1);
  265. ret = php_stream_tell(stream);
  266. if (ret == -1) RETURN_FALSE;
  267. RETURN_LONG(ret);
  268. }
  269. /* }}} */
  270. // copied from file.c and beautified
  271. /* {{{ proto int fseek(resource fp, int offset [, int whence])
  272. Seek on a file pointer */
  273. ZEND_API ZEND_FUNCTION(fseek)
  274. {
  275. zval **arg1, **arg2, **arg3;
  276. int argcount = ZEND_NUM_ARGS(), whence = SEEK_SET;
  277. php_stream *stream;
  278. if (argcount < 2 || argcount > 3 || zend_get_parameters_ex(argcount, &arg1, &arg2, &arg3) == FAILURE)
  279. {
  280. WRONG_PARAM_COUNT;
  281. }
  282. php_stream_from_zval(stream, arg1);
  283. convert_to_long_ex(arg2);
  284. if (argcount > 2)
  285. {
  286. convert_to_long_ex(arg3);
  287. whence = Z_LVAL_PP(arg3);
  288. }
  289. RETURN_LONG(php_stream_seek(stream, Z_LVAL_PP(arg2), whence));
  290. }
  291. // copied from file.c and beautified
  292. /* {{{ proto int fpassthru(resource fp)
  293. Output all remaining data from a file pointer */
  294. ZEND_API ZEND_FUNCTION(fpassthru)
  295. {
  296. zval **arg1;
  297. int size;
  298. php_stream *stream;
  299. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) WRONG_PARAM_COUNT;
  300. php_stream_from_zval(stream, arg1);
  301. size = php_stream_passthru(stream);
  302. RETURN_LONG(size);
  303. }
  304. /* }}} */
  305. #pragma managed
  306. // copied from file.c and beautified
  307. /* {{{ proto string fread(resource fp, int length)
  308. Binary-safe file read */
  309. ZEND_API ZEND_FUNCTION(fread)
  310. {
  311. zval **arg1, **arg2;
  312. int len;
  313. php_stream *stream;
  314. if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) WRONG_PARAM_COUNT;
  315. php_stream_from_zval(stream, arg1);
  316. convert_to_long_ex(arg2);
  317. len = Z_LVAL_PP(arg2);
  318. if (len < 0)
  319. {
  320. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative");
  321. RETURN_FALSE;
  322. }
  323. Z_STRVAL_P(return_value) = (char *)emalloc(len + 1);
  324. Z_STRLEN_P(return_value) = php_stream_read(stream, Z_STRVAL_P(return_value), len);
  325. /* needed because recv/read/gzread doesnt put a null at the end*/
  326. Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
  327. //if (PG(magic_quotes_runtime))
  328. if (PHP::Core::ScriptContext::CurrentContext->Config->Variables->QuoteRuntimeVariables)
  329. {
  330. Z_STRVAL_P(return_value) = php_addslashes(Z_STRVAL_P(return_value),
  331. Z_STRLEN_P(return_value), &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
  332. }
  333. Z_TYPE_P(return_value) = IS_STRING;
  334. }
  335. /* }}} */
  336. #pragma unmanaged
  337. // copied from main.c and beautified
  338. static FILE *php_fopen_wrapper_for_zend(const char *filename, char **opened_path)
  339. {
  340. TSRMLS_FETCH();
  341. return php_stream_open_wrapper_as_file((char *)filename, "rb",
  342. ENFORCE_SAFE_MODE | USE_PATH | IGNORE_URL_WIN | REPORT_ERRORS | STREAM_OPEN_FOR_INCLUDE, opened_path);
  343. }
  344. // copied from main.c and beautified
  345. static zend_bool php_open_wrapper_for_zend(const char *filename, struct _zend_file_handle *fh)
  346. {
  347. TSRMLS_FETCH();
  348. return php_stream_open_wrapper_as_file_handle((char *)filename, "rb",
  349. ENFORCE_SAFE_MODE | USE_PATH | IGNORE_URL_WIN | REPORT_ERRORS | STREAM_OPEN_FOR_INCLUDE, fh);
  350. }
  351. ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path) = php_fopen_wrapper_for_zend;
  352. ZEND_API zend_bool (*zend_open)(const char *filename, zend_file_handle *) = php_open_wrapper_for_zend;
  353. // copied from zend_language_scanner.c and beautified
  354. ZEND_API void zend_file_handle_dtor(zend_file_handle *fh)
  355. {
  356. switch (fh->type) {
  357. case ZEND_HANDLE_SOCKET_FD:
  358. #ifdef ZEND_WIN32
  359. closesocket(fh->handle.fd);
  360. break;
  361. #endif
  362. /* fall-through */
  363. case ZEND_HANDLE_FD:
  364. crtx_close(fh->handle.fd);
  365. break;
  366. case ZEND_HANDLE_FP:
  367. crtx_fclose(fh->handle.fp);
  368. break;
  369. case ZEND_HANDLE_FILENAME:
  370. /* We're only supposed to get here when destructing the used_files hash,
  371. * which doesn't really contain open files, but references to their names/paths
  372. */
  373. break;
  374. }
  375. if (fh->opened_path) {
  376. efree(fh->opened_path);
  377. fh->opened_path = NULL;
  378. }
  379. if (fh->free_filename && fh->filename) {
  380. efree(fh->filename);
  381. fh->filename = NULL;
  382. }
  383. }