1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2009 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.0 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_0.txt. |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 | |
15 | **** WARNING **** |
16 | |
17 | This module makes use of unRAR - free utility for RAR archives. |
18 | Its license states that you MUST NOT use its code to develop |
19 | a RAR (WinRAR) compatible archiver. |
20 | Please, read unRAR license for full information. |
21 | unRAR & RAR copyrights are owned by Eugene Roshal |
22 +----------------------------------------------------------------------+
23 | Author: Antony Dovgal <tony@daylessday.org> |
24 | Author: Gustavo Lopes <cataphract@php.net> |
25 +----------------------------------------------------------------------+
26 */
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #include <php.h>
33 #include <zend_exceptions.h>
34 #include "php_rar.h"
35
36 /* {{{ Globals with external linkage */
37 zend_class_entry *rarexception_ce_ptr;
38 /* }}} */
39
40 /* Functions with external linkage {{{ */
41 /* Functions with external linkage {{{ */
_rar_handle_error(int errcode TSRMLS_DC)42 int _rar_handle_error(int errcode TSRMLS_DC) /* {{{ */
43 {
44 return _rar_handle_error_ex("", errcode TSRMLS_CC);
45 }
46 /* }}} */
47
_rar_handle_error_ex(const char * preamble,int errcode TSRMLS_DC)48 int _rar_handle_error_ex(const char *preamble, int errcode TSRMLS_DC) /* {{{ */
49 {
50 const char *err = _rar_error_to_string(errcode);
51
52 if (err == NULL) {
53 return SUCCESS;
54 }
55
56 if (_rar_using_exceptions(TSRMLS_C)) {
57 zend_throw_exception_ex(rarexception_ce_ptr, errcode TSRMLS_CC,
58 "unRAR internal error: %s%s", preamble, err);
59 }
60 else {
61 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s", preamble, err);
62 }
63 return FAILURE;
64 }
65 /* }}} */
66
67 /* Errors not related to the unRAR library */
_rar_handle_ext_error(const char * format TSRMLS_DC,...)68 void _rar_handle_ext_error(const char *format TSRMLS_DC, ...) /* {{{ */
69 {
70 va_list arg;
71 char *message;
72
73 #if defined(ZTS) && PHP_MAJOR_VERSION < 7
74 va_start(arg, TSRMLS_C);
75 #else
76 va_start(arg, format);
77 #endif
78 vspprintf(&message, 0, format, arg);
79 va_end(arg);
80
81 if (_rar_using_exceptions(TSRMLS_C))
82 zend_throw_exception(rarexception_ce_ptr, message, -1L TSRMLS_CC);
83 else
84 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
85 efree(message);
86 }
87 /* }}} */
88
_rar_using_exceptions(TSRMLS_D)89 int _rar_using_exceptions(TSRMLS_D)
90 {
91 zval *pval;
92 pval = zend_read_static_property(rarexception_ce_ptr, "usingExceptions",
93 sizeof("usingExceptions") -1, (zend_bool) 1 TSRMLS_CC);
94 #if PHP_MAJOR_VERSION < 7
95 assert(Z_TYPE_P(pval) == IS_BOOL);
96 return Z_BVAL_P(pval);
97 #else
98 assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
99 return Z_TYPE_P(pval) == IS_TRUE;
100 #endif
101 }
102
103 /* returns a string or NULL if not an error */
_rar_error_to_string(int errcode)104 const char * _rar_error_to_string(int errcode) /* {{{ */
105 {
106 const char *ret;
107 switch (errcode) {
108 case 0:
109 /* no error */
110 case 1:
111 /* no error (comment completely read) */
112 case ERAR_END_ARCHIVE:
113 /* no error */
114 ret = NULL;
115 break;
116 case ERAR_NO_MEMORY:
117 ret = "ERAR_NO_MEMORY (not enough memory)";
118 break;
119 case ERAR_BAD_DATA:
120 ret = "ERAR_BAD_DATA";
121 break;
122 case ERAR_BAD_ARCHIVE:
123 ret = "ERAR_BAD_ARCHIVE";
124 break;
125 case ERAR_UNKNOWN_FORMAT:
126 ret = "ERAR_UNKNOWN_FORMAT";
127 break;
128 case ERAR_EOPEN:
129 ret = "ERAR_EOPEN (file open error)";
130 break;
131 case ERAR_ECREATE:
132 ret = "ERAR_ECREATE";
133 break;
134 case ERAR_ECLOSE:
135 ret = "ERAR_ECLOSE (error closing file)";
136 break;
137 case ERAR_EREAD:
138 ret = "ERAR_EREAD";
139 break;
140 case ERAR_EWRITE:
141 ret = "ERAR_EWRITE";
142 break;
143 case ERAR_SMALL_BUF:
144 ret = "ERAR_SMALL_BUF";
145 break;
146 case ERAR_UNKNOWN:
147 ret = "ERAR_UNKNOWN (unknown RAR error)";
148 break;
149 case ERAR_MISSING_PASSWORD:
150 ret = "ERAR_MISSING_PASSWORD (password needed but not specified)";
151 break;
152 default:
153 ret = "unknown RAR error (should not happen)";
154 break;
155 }
156 return ret;
157 }
158 /* }}} */
159 /* }}} */
160
161 /* {{{ proto bool RarException::setUsingExceptions(using_exceptions)
162 Set whether exceptions are to be used */
PHP_METHOD(rarexception,setUsingExceptions)163 PHP_METHOD(rarexception, setUsingExceptions)
164 {
165 zend_bool argval;
166 int result;
167
168 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &argval) == FAILURE ) {
169 return;
170 }
171
172 result = zend_update_static_property_bool(rarexception_ce_ptr,
173 "usingExceptions", sizeof("usingExceptions") -1,
174 (long) argval TSRMLS_CC);
175
176 if (result == FAILURE) {
177 php_error_docref(NULL TSRMLS_CC, E_WARNING,
178 "Could not set error handling mode. "
179 "This is a bug, please report it.");
180 return;
181 }
182 }
183 /* }}} */
184
185 /* {{{ proto bool RarException::isUsingExceptions()
186 Return whether exceptions are being used */
PHP_METHOD(rarexception,isUsingExceptions)187 PHP_METHOD(rarexception, isUsingExceptions)
188 {
189 #if PHP_MAJOR_VERSION < 7
190 zval **pval;
191 #else
192 zval *pval;
193 #endif
194
195 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE ) {
196 return;
197 }
198
199 /* or zend_read_static_property, which calls zend_std_get... after chg scope */
200 #if PHP_VERSION_ID < 50399
201 pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
202 sizeof("usingExceptions") -1, (zend_bool) 0 TSRMLS_CC);
203 #elif PHP_MAJOR_VERSION < 7
204 pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
205 sizeof("usingExceptions") -1, (zend_bool) 0, NULL TSRMLS_CC);
206 #else
207 zend_string *prop_name =
208 zend_string_init("usingExceptions", sizeof("usingExceptions") - 1, 0);
209 pval = zend_std_get_static_property(rarexception_ce_ptr, prop_name,
210 (zend_bool) 0);
211 zend_string_release(prop_name);
212 #endif
213 /* property always exists */
214 assert(pval != NULL);
215 #if PHP_MAJOR_VERSION < 7
216 assert(Z_TYPE_PP(pval) == IS_BOOL);
217 RETURN_ZVAL(*pval, 0, 0);
218 #else
219 assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
220 RETURN_ZVAL(pval, 0, 0);
221 #endif
222 }
223 /* }}} */
224
225 /* {{{ arginfo */
226 ZEND_BEGIN_ARG_INFO_EX(arginfo_rarexception_sue, 0, 0, 1)
227 ZEND_ARG_INFO(0, using_exceptions)
228 ZEND_END_ARG_INFO()
229
230 ZEND_BEGIN_ARG_INFO(arginfo_rarexception_void, 0)
231 ZEND_END_ARG_INFO()
232 /* }}} */
233
234 static zend_function_entry php_rarexception_class_functions[] = {
235 PHP_ME(rarexception, setUsingExceptions, arginfo_rarexception_sue, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
236 PHP_ME(rarexception, isUsingExceptions, arginfo_rarexception_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
237 {NULL, NULL, NULL}
238 };
239
minit_rarerror(TSRMLS_D)240 void minit_rarerror(TSRMLS_D) /* {{{ */
241 {
242 zend_class_entry ce;
243
244 INIT_CLASS_ENTRY(ce, "RarException", php_rarexception_class_functions);
245 #if PHP_MAJOR_VERSION < 7
246 rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
247 zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
248 #else
249 rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
250 zend_exception_get_default(TSRMLS_C));
251 #endif
252 rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
253 zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
254 sizeof("usingExceptions") -1, 0L /* FALSE */,
255 ZEND_ACC_STATIC TSRMLS_CC);
256 }
257 /* }}} */
258
259 #ifdef __cplusplus
260 }
261 #endif
262