Bug Summary

File:rootdir/src/webserver/src/php_core_lib.cpp
Warning:line 634, column 9
The 1st argument to 'fread' is a buffer with size 0 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 1) times the 3rd argument (which is 18446744073709551615)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name php_core_lib.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/src/webserver/src -fcoverage-compilation-dir=/rootdir/src/webserver/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I ../../.. -I ../.. -I ../../../src -I ../../../src/libs -I ../../../src/include -D USE_WX_EXTENSIONS -D WITH_LIBPNG -D HAVE_BFD -I /usr/lib/x86_64-linux-gnu/wx/include/gtk3-unicode-3.2 -I /usr/include/wx-3.2 -D _FILE_OFFSET_BITS=64 -D WXUSINGDLL -D __WXGTK__ -D wxUSE_GUI=0 -D WEBSERVERDIR="/usr/share/amule/webserver" -D YY_NO_INPUT -I /usr/include/upnp -D ENABLE_UPNP=1 -I /usr/include/libpng16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-register -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-01-14-142857-17216-1 -x c++ php_core_lib.cpp
1//
2// This file is part of the aMule Project.
3
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5// Copyright (c) 2005-2011 Froenchenko Leonid ( lfroen@gmail.com / http://www.amule.org )
6//
7// Any parts of this program derived from the xMule, lMule or eMule project,
8// or contributed by third-party developers are copyrighted by their
9// respective authors.
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24//
25
26#include "config.h"
27
28#include <string> // Do_not_auto_remove (g++-4.0.1)
29
30#ifdef HAVE_SYS_TYPES_H1
31# include <sys/types.h>
32#endif
33
34#ifdef PHP_STANDALONE_EN
35# include <map>
36# include <string>
37# include <list>
38# include <regex.h>
39#else
40# include "WebServer.h"
41# include <ec/cpp/ECSpecialTags.h>
42# include <wx/regex.h>
43# include <wx/datetime.h>
44#endif
45
46#include "php_syntree.h"
47#include "php_core_lib.h"
48#include <stdarg.h>
49
50#ifdef ENABLE_NLS1
51#include <libintl.h>
52#endif
53
54/*
55 * Built-in php functions. Those are both library and core internals.
56 *
57 * I'm not going event to get near to what Zend provide, but
58 * at least base things must be here
59 */
60
61/*
62 * Print info about variable: php var_dump()
63 */
64void php_var_dump(PHP_VALUE_NODE *node, int ident, int ref)
65{
66 for(int i = 0; i < ident;i++) {
67 printf("\t");
68 }
69 if ( ref ) printf("&");
70 switch(node->type) {
71 case PHP_VAL_BOOL: printf("bool(%s)\n", node->int_val ? "true" : "false"); break;
72 case PHP_VAL_INT: printf("int(%" PRIu64"l" "u" ")\n", node->int_val); break;
73 case PHP_VAL_FLOAT: printf("float(%f)\n", node->float_val); break;
74 case PHP_VAL_STRING: printf("string(%d) \"%s\"\n", (int)strlen(node->str_val), node->str_val); break;
75 case PHP_VAL_OBJECT: printf("Object(%s)\n", node->obj_val.class_name); break;
76 case PHP_VAL_ARRAY: {
77 int arr_size = array_get_size(node);
78 printf("array(%d) {\n", arr_size);
79 for(int i = 0; i < arr_size;i++) {
80 const std::string &curr_key = array_get_ith_key(node, i);
81 PHP_VAR_NODE *curr_val = array_get_by_str_key(node, curr_key);
82 printf("\t[%s]=>\n", curr_key.c_str());
83 php_var_dump(&curr_val->value, ident+1, curr_val->ref_count > 1);
84 }
85 for(int i = 0; i < ident;i++) {
86 printf("\t");
87 }
88 printf("}\n");
89 break;
90 }
91 case PHP_VAL_NONE: printf("NULL\n"); break;
92 case PHP_VAL_VAR_NODE:
93 case PHP_VAL_INT_DATA: assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
; break;
94 }
95}
96
97void php_native_var_dump(PHP_VALUE_NODE *)
98{
99 PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, "__param_0");
100 if ( si ) {
101 assert((si->type == PHP_SCOPE_VAR)||(si->type == PHP_SCOPE_PARAM))(static_cast <bool> ((si->type == PHP_SCOPE_VAR)||(si
->type == PHP_SCOPE_PARAM)) ? void (0) : __assert_fail ("(si->type == PHP_SCOPE_VAR)||(si->type == PHP_SCOPE_PARAM)"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
102 php_var_dump(&si->var->value, 0, 0);
103 } else {
104 php_report_error(PHP_ERROR, "Invalid or missing argument");
105 }
106}
107
108
109/*
110 * Sorting stl-way requires operator ">"
111 */
112class SortElem {
113 public:
114 SortElem() {}
115 SortElem(PHP_VAR_NODE *p) { obj = p; }
116
117 PHP_VAR_NODE *obj;
118 static PHP_SYN_FUNC_DECL_NODE *callback;
119
120 friend bool operator<(const SortElem &o1, const SortElem &o2);
121};
122
123PHP_SYN_FUNC_DECL_NODE *SortElem::callback = 0;
124
125bool operator<(const SortElem &o1, const SortElem &o2)
126{
127 PHP_VALUE_NODE result;
128
129 value_value_assign(&SortElem::callback->params[0].si_var->var->value, &o1.obj->value);
130 value_value_assign(&SortElem::callback->params[1].si_var->var->value, &o2.obj->value);
131
132 switch_push_scope_table((PHP_SCOPE_TABLE_TYPE *)SortElem::callback->scope);
133
134 //
135 // params passed by-value, all & notations ignored
136 //
137 result.type = PHP_VAL_NONE;
138 php_execute(SortElem::callback->code, &result);
139 cast_value_dnum(&result);
140 //
141 // restore stack, free arg list
142 //
143 switch_pop_scope_table(0);
144
145 value_value_free(&SortElem::callback->params[0].si_var->var->value);
146 value_value_free(&SortElem::callback->params[1].si_var->var->value);
147
148 return result.int_val != 0;
149}
150
151void php_native_usort(PHP_VALUE_NODE *)
152{
153 PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, "__param_0");
154 if ( !si || (si->var->value.type != PHP_VAL_ARRAY)) {
155 php_report_error(PHP_ERROR, "Invalid or missing argument (array)");
156 return;
157 }
158 PHP_VAR_NODE *array = si->var;
159 si = get_scope_item(g_current_scope, "__param_1");
160 if ( !si || (si->var->value.type != PHP_VAL_STRING)) {
161 php_report_error(PHP_ERROR, "Invalid or missing argument (func name)");
162 return;
163 }
164 char *cmp_func_name = si->var->value.str_val;
165 si = get_scope_item(g_global_scope, cmp_func_name);
166 if ( !si || (si->type != PHP_SCOPE_FUNC)) {
167 php_report_error(PHP_ERROR, "Compare function [%s] not found", cmp_func_name);
168 return;
169 }
170 PHP_SYN_FUNC_DECL_NODE *func_decl = si->func->func_decl;
171
172 //
173 // usort invalidates keys, and sorts values
174 //
175 PHP_ARRAY_TYPE *arr_obj = (PHP_ARRAY_TYPE *)array->value.ptr_val;
176 //
177 // create vector of values
178 //
179 if ( arr_obj->array.empty() ) {
180 php_report_error(PHP_WARNING, "Sorting array of size 0");
181 return;
182 }
183
184 std::list<SortElem> sort_list;
185 for(PHP_ARRAY_ITER_TYPE i = arr_obj->array.begin(); i != arr_obj->array.end(); ++i) {
186 sort_list.push_back(SortElem(i->second));
187 }
188 SortElem::callback = func_decl;
189 sort_list.sort();
190
191 arr_obj->array.clear();
192 arr_obj->sorted_keys.clear();
193 unsigned int key = 0;
194 for(std::list<SortElem>::iterator i = sort_list.begin(); i != sort_list.end(); ++i) {
195 array_add_to_int_key(&array->value, key++, i->obj);
196 }
197
198}
199
200
201/*
202 * String functions
203 */
204void php_native_strlen(PHP_VALUE_NODE *result)
205{
206 PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, "__param_0");
207 if ( si ) {
208 PHP_VALUE_NODE *param = &si->var->value;
209 cast_value_str(param);
210 if ( result ) {
211 cast_value_dnum(result);
212 result->int_val = strlen(param->str_val);
213 }
214 } else {
215 php_report_error(PHP_ERROR, "Invalid or missing argument");
216 }
217}
218
219void php_native_count(PHP_VALUE_NODE *result)
220{
221 PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, "__param_0");
222 if ( si ) {
223 PHP_VALUE_NODE *param = &si->var->value;
224 if ( result ) {
225 cast_value_dnum(result);
226 if ( si->var->value.type != PHP_VAL_ARRAY ) {
227 result->int_val = 0;
228 } else {
229 result->int_val = array_get_size(param);
230 }
231 }
232 } else {
233 php_report_error(PHP_ERROR, "Invalid or missing argument");
234 }
235}
236
237void php_native_isset(PHP_VALUE_NODE *result)
238{
239 PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, "__param_0");
240 if ( si ) {
241 PHP_VALUE_NODE *param = &si->var->value;
242 cast_value_str(param);
243 if ( result ) {
244 cast_value_bool(result);
245 result->int_val = (si->var->value.type == PHP_VAL_NONE) ? 0 : 1;
246 }
247 } else {
248 php_report_error(PHP_ERROR, "Invalid or missing argument");
249 }
250}
251
252void php_native_substr(PHP_VALUE_NODE * /*result*/)
253{
254 PHP_SCOPE_ITEM *si_str = get_scope_item(g_current_scope, "__param_0");
255 PHP_VALUE_NODE *str = &si_str->var->value;
256 if ( si_str ) {
257 cast_value_str(str);
258 } else {
259 php_report_error(PHP_ERROR, "Invalid or missing argument 'str' for 'substr'");
260 return;
261 }
262 PHP_SCOPE_ITEM *si_start = get_scope_item(g_current_scope, "__param_1");
263 PHP_VALUE_NODE *start = &si_start->var->value;
264 if ( si_start ) {
265 cast_value_dnum(start);
266 } else {
267 php_report_error(PHP_ERROR, "Invalid or missing argument 'start' for 'substr'");
268 return;
269 }
270 // 3-rd is optional
271 PHP_SCOPE_ITEM *si_end = get_scope_item(g_current_scope, "__param_2");
272 PHP_VALUE_NODE end = { PHP_VAL_INT, { 0 } };
273 if ( si_end ) {
274 end = si_end->var->value;
275 }
276 cast_value_dnum(&end);
277
278
279}
280
281
282void php_native_split(PHP_VALUE_NODE *result)
283{
284 if ( result ) {
285 cast_value_array(result);
286 } else {
287 return;
288 }
289 PHP_VALUE_NODE *pattern, *string_to_split;
290 PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, "__param_0");
291 if ( si ) {
292 pattern = &si->var->value;
293 cast_value_str(pattern);
294 } else {
295 php_report_error(PHP_ERROR, "Invalid or missing argument: pattern");
296 return;
297 }
298 si = get_scope_item(g_current_scope, "__param_1");
299 if ( si ) {
300 string_to_split = &si->var->value;
301 cast_value_str(string_to_split);
302 } else {
303 php_report_error(PHP_ERROR, "Invalid or missing argument: string");
304 return;
305 }
306 si = get_scope_item(g_current_scope, "__param_2");
307 if ( si ) {
308 PHP_VALUE_NODE *split_limit = &si->var->value;
309 cast_value_dnum(split_limit);
310 } else {
311 php_report_error(PHP_ERROR, "Invalid or missing argument: string");
312 return;
313 }
314#ifdef PHP_STANDALONE_EN
315 regex_t preg;
316 int reg_result = regcomp(&preg, pattern->str_val, REG_EXTENDED);
317 if ( reg_result ) {
318 char error_buff[256];
319 regerror(reg_result, &preg, error_buff, sizeof(error_buff));
320 php_report_error(PHP_ERROR, "Failed in regcomp: %s", error_buff);
321#else
322 wxRegEx preg;
323 if (!preg.Compile(wxString(char2unicode(pattern->str_val)), wxRE_EXTENDED)) {
324 php_report_error(PHP_ERROR, "Failed in Compile of: %s", pattern->str_val);
325#endif
326 return;
327 }
328
329#ifdef PHP_STANDALONE_EN
330 size_t nmatch = strlen(string_to_split->str_val);
331 regmatch_t *pmatch = new regmatch_t[nmatch];
332#endif
333 char *str_2_match = string_to_split->str_val;
334 char *tmp_buff = new char[strlen(string_to_split->str_val)+1];
335
336 while ( 1 ) {
337// printf("matching: %s\n", str_2_match);
338#ifdef PHP_STANDALONE_EN
339 reg_result = regexec(&preg, str_2_match, nmatch, pmatch, 0);
340 if ( reg_result ) {
341#else
342 if (!preg.Matches(wxString(char2unicode(str_2_match)))) {
343#endif
344 // no match
345 break;
346 }
347#ifndef PHP_STANDALONE_EN
348 // get matching position
349 size_t start, len;
350 if (!preg.GetMatch(&start, &len)) {
351 break; // shouldn't happen
352 }
353#endif
354 /*
355 * I will use only first match, since I don't see any sense to have more
356 * then 1 match in split() call
357 */
358#ifdef PHP_STANDALONE_EN
359 for(int i = 0; i < pmatch[0].rm_so; i++) {
360#else
361 for(size_t i = 0; i < start; i++) {
362#endif
363 tmp_buff[i] = str_2_match[i];
364 }
365#ifdef PHP_STANDALONE_EN
366 tmp_buff[pmatch[0].rm_so] = 0;
367#else
368 tmp_buff[start] = 0;
369#endif
370// printf("Match added [%s]\n", tmp_buff);
371
372 PHP_VAR_NODE *match_val = array_push_back(result);
373 match_val->value.type = PHP_VAL_STRING;
374 match_val->value.str_val = strdup(tmp_buff);
375
376#ifdef PHP_STANDALONE_EN
377 str_2_match += pmatch[0].rm_eo;
378#else
379 str_2_match += start + len;
380#endif
381 }
382
383 PHP_VAR_NODE *match_val = array_push_back(result);
384 match_val->value.type = PHP_VAL_STRING;
385 match_val->value.str_val = strdup(str_2_match);
386
387 delete [] tmp_buff;
388#ifdef PHP_STANDALONE_EN
389 delete [] pmatch;
390 regfree(&preg);
391#endif
392}
393
394#ifdef ENABLE_NLS1
395
396void php_native_gettext(PHP_VALUE_NODE *result)
397{
398 PHP_SCOPE_ITEM *si_str = get_scope_item(g_current_scope, "__param_0");
399 PHP_VALUE_NODE *str = &si_str->var->value;
400 if ( si_str ) {
401 cast_value_str(str);
402 } else {
403 php_report_error(PHP_ERROR, "Invalid or missing argument 'msgid' for 'gettext'");
404 return;
405 }
406 if ( result ) {
407 cast_value_dnum(result);
408 result->type = PHP_VAL_STRING;
409 result->str_val = strdup(gettext(str->str_val));
410 }
411}
412
413void php_native_gettext_noop(PHP_VALUE_NODE *result)
414{
415 PHP_SCOPE_ITEM *si_str = get_scope_item(g_current_scope, "__param_0");
416 PHP_VALUE_NODE *str = &si_str->var->value;
417 if ( si_str ) {
418 cast_value_str(str);
419 } else {
420 php_report_error(PHP_ERROR, "Invalid or missing argument 'msgid' for 'gettext_noop'");
421 return;
422 }
423 if ( result ) {
424 cast_value_dnum(result);
425 result->type = PHP_VAL_STRING;
426 result->str_val = strdup(str->str_val);
427 }
428}
429
430void php_native_ngettext(PHP_VALUE_NODE *result)
431{
432 PHP_SCOPE_ITEM *si_msgid = get_scope_item(g_current_scope, "__param_0");
433 PHP_VALUE_NODE *msgid = &si_msgid->var->value;
434 if ( si_msgid ) {
435 cast_value_str(msgid);
436 } else {
437 php_report_error(PHP_ERROR, "Invalid or missing argument 'msgid' for 'ngettext'");
438 return;
439 }
440 PHP_SCOPE_ITEM *si_msgid_plural = get_scope_item(g_current_scope, "__param_1");
441 PHP_VALUE_NODE *msgid_plural = &si_msgid_plural->var->value;
442 if ( si_msgid_plural ) {
443 cast_value_str(msgid_plural);
444 } else {
445 php_report_error(PHP_ERROR, "Invalid or missing argument 'msgid_plural' for 'ngettext'");
446 return;
447 }
448 PHP_SCOPE_ITEM *si_count = get_scope_item(g_current_scope, "__param_2");
449 PHP_VALUE_NODE *count = &si_count->var->value;
450 if ( si_count ) {
451 cast_value_dnum(count);
452 } else {
453 php_report_error(PHP_ERROR, "Invalid or missing argument 'count' for 'ngettext'");
454 return;
455 }
456 if ( result ) {
457 cast_value_dnum(result);
458 result->type = PHP_VAL_STRING;
459 result->str_val = strdup(ngettext(msgid->str_val, msgid_plural->str_val, count->int_val));
460 }
461}
462#endif
463
464PHP_BLTIN_FUNC_DEF core_lib_funcs[] = {
465 {
466 "var_dump",
467 1,
468 php_native_var_dump,
469 },
470 {
471 "strlen",
472 1, php_native_strlen,
473 },
474 {
475 "count",
476 1, php_native_count,
477 },
478 {
479 "isset",
480 1, php_native_isset,
481 },
482 {
483 "usort",
484 2,
485 php_native_usort,
486 },
487 {
488 "split",
489 3,
490 php_native_split,
491 },
492#ifdef ENABLE_NLS1
493 {
494 "_",
495 1, php_native_gettext,
496 },
497 {
498 "gettext",
499 1, php_native_gettext,
500 },
501 {
502 "gettext_noop",
503 1, php_native_gettext_noop,
504 },
505 {
506 "ngettext",
507 3, php_native_ngettext,
508 },
509#endif
510 { 0, 0, 0, },
511};
512
513void php_init_core_lib()
514{
515 // load function definitions
516 PHP_BLTIN_FUNC_DEF *curr_def = core_lib_funcs;
517 while ( curr_def->name ) {
518 php_add_native_func(curr_def);
519 curr_def++;
520 }
521}
522
523//
524// lexer has no include file
525//
526extern "C"
527void php_set_input_buffer(char *buf, int len);
528
529CPhPLibContext::CPhPLibContext(CWebServerBase *server, const char *file)
530{
531 g_curr_context = this;
532
533 m_server = server;
534
535 php_engine_init();
536 phpin = fopen(file, "r");
537 if ( !phpin ) {
538 return;
539 }
540
541 phpparse();
542
543 m_syn_tree_top = g_syn_tree_top;
544 m_global_scope = g_global_scope;
545}
546
547CPhPLibContext::CPhPLibContext(CWebServerBase *server, char *php_buf, int len)
548{
549 g_curr_context = this;
550
551 m_server = server;
552
553 php_engine_init();
554
555 m_global_scope = g_global_scope;
556
557 php_set_input_buffer(php_buf, len);
558 phpparse();
559
560 m_syn_tree_top = g_syn_tree_top;
561}
562
563CPhPLibContext::~CPhPLibContext()
564{
565 SetContext();
566 php_engine_free();
567}
568
569void CPhPLibContext::SetContext()
570{
571 g_syn_tree_top = m_syn_tree_top;
572 g_global_scope = m_global_scope;
573}
574
575void CPhPLibContext::Execute(CWriteStrBuffer *buf)
576{
577 m_curr_str_buffer = buf;
578
579 PHP_VALUE_NODE val;
580 php_execute(g_syn_tree_top, &val);
581}
582
583CPhPLibContext *CPhPLibContext::g_curr_context = 0;
584
585/*
586 * For simplicity and performance sake, this function can
587 * only handle limited-length printf's. In should be NOT be used
588 * for string concatenation like printf("xyz %s %s", s1, s2).
589 *
590 * Engine will call Print for "print" and "echo"
591 */
592void CPhPLibContext::Printf(const char *str, ...)
593{
594 va_list args;
595
596 va_start(args, str)__builtin_va_start(args, str);
597 if ( !g_curr_context || !g_curr_context->m_curr_str_buffer ) {
598 vprintf(str, args);
599 } else {
600 char buf[4096];
601 vsnprintf(buf, sizeof(buf), str, args);
602 g_curr_context->m_curr_str_buffer->Write(buf);
603 }
604 va_end(args)__builtin_va_end(args);
605}
606
607void CPhPLibContext::Print(const char *str)
608{
609 if ( !g_curr_context || !g_curr_context->m_curr_str_buffer ) {
610 printf("%s", str);
611 } else {
612 g_curr_context->m_curr_str_buffer->Write(str);
613 }
614}
615
616
617CPhpFilter::CPhpFilter(CWebServerBase *server, CSession *sess,
618 const char *file, CWriteStrBuffer *buff)
619{
620 FILE *f = fopen(file, "r");
1
Assuming that 'fopen' is successful
621 if ( !f
1.1
'f' is non-null
) {
2
Taking false branch
622 printf("ERROR: php can not open source file [%s]\n", file);
623 return;
624 }
625 if ( fseek(f, 0, SEEK_END2) != 0 ) {
3
Taking false branch
626 printf("ERROR: fseek failed on php source file [%s]\n", file);
627 fclose(f);
628 return;
629 }
630 int size = ftell(f);
4
'size' initialized to -1
631 char *buf = new char [size+1];
5
Storing uninitialized value
6
'buf' initialized here
632 rewind(f);
633 // fread may actually read less if it is a CR-LF-file in Windows
634 size = fread(buf, 1, size, f);
7
The 1st argument to 'fread' is a buffer with size 0 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 1) times the 3rd argument (which is 18446744073709551615)
635 buf[size] = 0;
636 fclose(f);
637 char *scan_ptr = buf;
638 char *curr_code_end = buf;
639 while ( strlen(scan_ptr) ) {
640 scan_ptr = strstr(scan_ptr, "<?php");
641 if ( !scan_ptr ) {
642 buff->Write(curr_code_end);
643 break;
644 }
645 if ( scan_ptr != curr_code_end ) {
646 buff->Write(curr_code_end, scan_ptr - curr_code_end);
647 }
648 curr_code_end = strstr(scan_ptr, "?>");
649 if ( !curr_code_end ) {
650 break;
651 }
652 curr_code_end += 2; // include "?>" in buffer
653
654 int len = curr_code_end - scan_ptr;
655
656 CPhPLibContext *context = new CPhPLibContext(server, scan_ptr, len);
657
658#ifndef PHP_STANDALONE_EN
659 load_session_vars("HTTP_GET_VARS", sess->m_get_vars);
660 load_session_vars("_SESSION", sess->m_vars);
661#endif
662
663 context->Execute(buff);
664
665#ifndef PHP_STANDALONE_EN
666 save_session_vars(sess->m_vars);
667#endif
668
669 delete context;
670
671 scan_ptr = curr_code_end;
672 }
673
674#ifndef PHP_STANDALONE_EN
675 sess->m_get_vars.clear();
676#endif
677
678 delete [] buf;
679}
680
681
682/*
683 * String buffer: almost same as regular 'string' class, but,
684 * without reallocation when full. Instead, new buffer is
685 * allocated, and added to list
686 */
687CWriteStrBuffer::CWriteStrBuffer()
688{
689 m_alloc_size = 1024;
690 m_total_length = 0;
691
692 AllocBuf();
693}
694
695CWriteStrBuffer::~CWriteStrBuffer()
696{
697 for(std::list<char *>::iterator i = m_buf_list.begin(); i != m_buf_list.end(); ++i) {
698 delete [] *i;
699 }
700 delete [] m_curr_buf;
701}
702
703void CWriteStrBuffer::AllocBuf()
704{
705 m_curr_buf = new char [m_alloc_size];
706 m_buf_ptr = m_curr_buf;
707 m_curr_buf_left = m_alloc_size;
708}
709
710void CWriteStrBuffer::Write(const char *s, int len)
711{
712 if ( len == -1 ) {
713 len = strlen(s);
714 }
715 m_total_length += len;
716
717 while ( len ) {
718 if ( (len + 1) <= m_curr_buf_left ) {
719 strncpy(m_buf_ptr, s, len);
720 m_buf_ptr += len;
721 m_curr_buf_left -= len;
722 len = 0;
723 } else {
724 memcpy(m_buf_ptr, s, m_curr_buf_left);
725 int rem_len = len - m_curr_buf_left;
726 s += m_curr_buf_left;
727
728 len = rem_len;
729 m_buf_list.push_back(m_curr_buf);
730 AllocBuf();
731 }
732 }
733}
734
735void CWriteStrBuffer::CopyAll(char *dst_buffer)
736{
737 char *curr_ptr = dst_buffer;
738 int rem_size = m_total_length;
739 for(std::list<char *>::iterator i = m_buf_list.begin(); i != m_buf_list.end(); ++i) {
740 memcpy(curr_ptr, *i, m_alloc_size);
741 rem_size -= m_alloc_size;
742 curr_ptr += m_alloc_size;
743 }
744 if ( rem_size ) {
745 memcpy(curr_ptr, m_curr_buf, rem_size);
746 }
747 *(curr_ptr + rem_size) = 0;
748}
749
750void load_session_vars(const char *target, std::map<std::string, std::string> &varmap)
751{
752 PHP_EXP_NODE *sess_vars_exp_node = get_var_node(target);
753 PHP_VAR_NODE *sess_vars = sess_vars_exp_node->var_si_node->var;
754 // i'm not building exp tree, node not needed
755 delete sess_vars_exp_node;
756 cast_value_array(&sess_vars->value);
757 for(std::map<std::string, std::string>::iterator i = varmap.begin(); i != varmap.end(); ++i) {
758 PHP_VAR_NODE *curr_var = array_get_by_str_key(&sess_vars->value, i->first);
759 PHP_VALUE_NODE val;
760 val.type = PHP_VAL_STRING;
761 val.str_val = const_cast<char *>(i->second.c_str());
762 value_value_assign(&curr_var->value, &val);
763 }
764}
765
766void save_session_vars(std::map<std::string, std::string> &varmap)
767{
768 PHP_EXP_NODE *sess_vars_exp_node = get_var_node("_SESSION");
769 PHP_VAR_NODE *sess_vars = sess_vars_exp_node->var_si_node->var;
770
771 delete sess_vars_exp_node;
772 if ( sess_vars->value.type != PHP_VAL_ARRAY ) {
773 return;
774 }
775
776 for(int i = 0; i < array_get_size(&sess_vars->value); i++) {
777 std::string s = array_get_ith_key(&sess_vars->value, i);
778 PHP_VAR_NODE *var = array_get_by_str_key(&sess_vars->value, s);
779 cast_value_str(&var->value);
780 varmap[s] = var->value.str_val;
781 }
782}
783// File_checked_for_headers