Coverage Report

Created: 2025-07-23 06:33

/src/php-src/ext/standard/info.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
   +----------------------------------------------------------------------+
3
   | Copyright (c) The PHP Group                                          |
4
   +----------------------------------------------------------------------+
5
   | This source file is subject to version 3.01 of the PHP license,      |
6
   | that is bundled with this package in the file LICENSE, and is        |
7
   | available through the world-wide-web at the following url:           |
8
   | https://www.php.net/license/3_01.txt                                 |
9
   | If you did not receive a copy of the PHP license and are unable to   |
10
   | obtain it through the world-wide-web, please send a note to          |
11
   | license@php.net so we can mail you a copy immediately.               |
12
   +----------------------------------------------------------------------+
13
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
14
   |          Zeev Suraski <zeev@php.net>                                 |
15
   |          Colin Viebrock <colin@viebrock.ca>                          |
16
   +----------------------------------------------------------------------+
17
*/
18
19
#include "php.h"
20
#include "php_ini.h"
21
#include "php_globals.h"
22
#include "ext/standard/head.h"
23
#include "ext/standard/html.h"
24
#include "info.h"
25
#include "credits.h"
26
#include "css.h"
27
#include "SAPI.h"
28
#include <time.h>
29
#include "php_main.h"
30
#include "zend_globals.h"   /* needs ELS */
31
#include "zend_extensions.h"
32
#include "zend_highlight.h"
33
#ifdef HAVE_SYS_UTSNAME_H
34
#include <sys/utsname.h>
35
#endif
36
#include "url.h"
37
38
#ifdef PHP_WIN32
39
# include "winver.h"
40
#endif
41
42
44
#define SECTION(name) if (!sapi_module.phpinfo_as_text) { \
43
0
              php_info_print("<h2>" name "</h2>\n"); \
44
44
            } else { \
45
44
              php_info_print_table_start(); \
46
44
              php_info_print_table_header(1, name); \
47
44
              php_info_print_table_end(); \
48
44
            } \
49
50
PHPAPI extern char *php_ini_opened_path;
51
PHPAPI extern char *php_ini_scanned_path;
52
PHPAPI extern char *php_ini_scanned_files;
53
54
static ZEND_COLD size_t php_info_print_html_esc(const char *str, size_t len) /* {{{ */
55
0
{
56
0
  size_t written;
57
0
  zend_string *new_str;
58
59
0
  new_str = php_escape_html_entities((const unsigned char *) str, len, 0, ENT_QUOTES, "utf-8");
60
0
  written = php_output_write(ZSTR_VAL(new_str), ZSTR_LEN(new_str));
61
0
  zend_string_free(new_str);
62
0
  return written;
63
0
}
64
/* }}} */
65
66
static ZEND_COLD size_t php_info_printf(const char *fmt, ...) /* {{{ */
67
88
{
68
88
  char *buf;
69
88
  size_t len, written;
70
88
  va_list argv;
71
72
88
  va_start(argv, fmt);
73
88
  len = vspprintf(&buf, 0, fmt, argv);
74
88
  va_end(argv);
75
76
88
  written = php_output_write(buf, len);
77
88
  efree(buf);
78
88
  return written;
79
88
}
80
/* }}} */
81
82
static zend_always_inline size_t php_info_print(const char *str) /* {{{ */
83
18.4k
{
84
18.4k
  return php_output_write(str, strlen(str));
85
18.4k
}
86
/* }}} */
87
88
static ZEND_COLD void php_info_print_stream_hash(const char *name, HashTable *ht) /* {{{ */
89
33
{
90
33
  zend_string *key;
91
92
33
  if (ht) {
93
33
    if (zend_hash_num_elements(ht)) {
94
33
      int first = 1;
95
96
33
      if (!sapi_module.phpinfo_as_text) {
97
0
        php_info_printf("<tr><td class=\"e\">Registered %s</td><td class=\"v\">", name);
98
33
      } else {
99
33
        php_info_printf("\nRegistered %s => ", name);
100
33
      }
101
102
33
      if (!HT_IS_PACKED(ht)) {
103
418
        ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) {
104
418
          if (key) {
105
176
            if (first) {
106
33
              first = 0;
107
143
            } else {
108
143
              php_info_print(", ");
109
143
            }
110
176
            if (!sapi_module.phpinfo_as_text) {
111
0
              php_info_print_html_esc(ZSTR_VAL(key), ZSTR_LEN(key));
112
176
            } else {
113
176
              php_info_print(ZSTR_VAL(key));
114
176
            }
115
176
          }
116
418
        } ZEND_HASH_FOREACH_END();
117
33
      }
118
119
33
      if (!sapi_module.phpinfo_as_text) {
120
0
        php_info_print("</td></tr>\n");
121
0
      }
122
33
    } else {
123
0
      char reg_name[128];
124
0
      snprintf(reg_name, sizeof(reg_name), "Registered %s", name);
125
0
      php_info_print_table_row(2, reg_name, "none registered");
126
0
    }
127
33
  } else {
128
0
    php_info_print_table_row(2, name, "disabled");
129
0
  }
130
33
}
131
/* }}} */
132
133
PHPAPI ZEND_COLD void php_info_print_module(zend_module_entry *zend_module) /* {{{ */
134
198
{
135
198
  if (zend_module->info_func || zend_module->version) {
136
198
    if (!sapi_module.phpinfo_as_text) {
137
0
      zend_string *url_name = php_url_encode(zend_module->name, strlen(zend_module->name));
138
139
0
      zend_str_tolower(ZSTR_VAL(url_name), ZSTR_LEN(url_name));
140
0
      php_info_printf("<h2><a name=\"module_%s\" href=\"#module_%s\">%s</a></h2>\n", ZSTR_VAL(url_name), ZSTR_VAL(url_name), zend_module->name);
141
142
0
      efree(url_name);
143
198
    } else {
144
198
      php_info_print_table_start();
145
198
      php_info_print_table_header(1, zend_module->name);
146
198
      php_info_print_table_end();
147
198
    }
148
198
    if (zend_module->info_func) {
149
187
      zend_module->info_func(zend_module);
150
187
    } else {
151
11
      php_info_print_table_start();
152
11
      php_info_print_table_row(2, "Version", zend_module->version);
153
11
      php_info_print_table_end();
154
11
      DISPLAY_INI_ENTRIES();
155
11
    }
156
198
  } else {
157
0
    if (!sapi_module.phpinfo_as_text) {
158
0
      php_info_printf("<tr><td class=\"v\">%s</td></tr>\n", zend_module->name);
159
0
    } else {
160
0
      php_info_printf("%s\n", zend_module->name);
161
0
    }
162
0
  }
163
198
}
164
/* }}} */
165
166
/* {{{ php_print_gpcse_array */
167
static ZEND_COLD void php_print_gpcse_array(char *name, size_t name_length)
168
77
{
169
77
  zval *data, *tmp;
170
77
  zend_string *string_key;
171
77
  zend_ulong num_key;
172
77
  zend_string *key;
173
174
77
  key = zend_string_init(name, name_length, 0);
175
77
  zend_is_auto_global(key);
176
177
77
  if ((data = zend_hash_find_deref(&EG(symbol_table), key)) != NULL && (Z_TYPE_P(data) == IS_ARRAY)) {
178
1.79k
    ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), num_key, string_key, tmp) {
179
1.79k
      if (!sapi_module.phpinfo_as_text) {
180
0
        php_info_print("<tr>");
181
0
        php_info_print("<td class=\"e\">");
182
0
      }
183
184
1.79k
      php_info_print("$");
185
1.79k
      php_info_print(name);
186
1.79k
      php_info_print("['");
187
188
1.79k
      if (string_key != NULL) {
189
858
        if (!sapi_module.phpinfo_as_text) {
190
0
          php_info_print_html_esc(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
191
858
        } else {
192
858
          php_info_print(ZSTR_VAL(string_key));
193
858
        }
194
858
      } else {
195
0
        php_info_printf(ZEND_ULONG_FMT, num_key);
196
0
      }
197
1.79k
      php_info_print("']");
198
1.79k
      if (!sapi_module.phpinfo_as_text) {
199
0
        php_info_print("</td><td class=\"v\">");
200
858
      } else {
201
858
        php_info_print(" => ");
202
858
      }
203
1.79k
      ZVAL_DEREF(tmp);
204
1.79k
      if (Z_TYPE_P(tmp) == IS_ARRAY) {
205
11
        if (!sapi_module.phpinfo_as_text) {
206
0
          zend_string *str = zend_print_zval_r_to_str(tmp, 0);
207
0
          php_info_print("<pre>");
208
0
          php_info_print_html_esc(ZSTR_VAL(str), ZSTR_LEN(str));
209
0
          php_info_print("</pre>");
210
0
          zend_string_release_ex(str, 0);
211
11
        } else {
212
11
          zend_print_zval_r(tmp, 0);
213
11
        }
214
847
      } else {
215
847
        zend_string *tmp2;
216
847
        zend_string *str = zval_get_tmp_string(tmp, &tmp2);
217
218
847
        if (!sapi_module.phpinfo_as_text) {
219
0
          if (ZSTR_LEN(str) == 0) {
220
0
            php_info_print("<i>no value</i>");
221
0
          } else {
222
0
            php_info_print_html_esc(ZSTR_VAL(str), ZSTR_LEN(str));
223
0
          }
224
847
        } else {
225
847
          php_info_print(ZSTR_VAL(str));
226
847
        }
227
228
847
        zend_tmp_string_release(tmp2);
229
847
      }
230
1.79k
      if (!sapi_module.phpinfo_as_text) {
231
0
        php_info_print("</td></tr>\n");
232
858
      } else {
233
858
        php_info_print("\n");
234
858
      }
235
1.79k
    } ZEND_HASH_FOREACH_END();
236
77
  }
237
77
  zend_string_efree(key);
238
77
}
239
/* }}} */
240
241
/* {{{ php_info_print_style */
242
PHPAPI ZEND_COLD void ZEND_COLD php_info_print_style(void)
243
0
{
244
0
  php_info_printf("<style type=\"text/css\">\n");
245
0
  php_info_print_css();
246
0
  php_info_printf("</style>\n");
247
0
}
248
/* }}} */
249
250
#ifdef PHP_WIN32
251
/* {{{  */
252
253
static char* php_get_windows_name()
254
{
255
  OSVERSIONINFOEX osvi = EG(windows_version_info);
256
  SYSTEM_INFO si;
257
  DWORD dwType;
258
  const char *major = NULL, *sub = NULL;
259
260
  ZeroMemory(&si, sizeof(SYSTEM_INFO));
261
262
  GetNativeSystemInfo(&si);
263
264
  if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) {
265
    if (osvi.dwMajorVersion == 10) {
266
      if (osvi.dwMinorVersion == 0) {
267
        if (osvi.wProductType == VER_NT_WORKSTATION) {
268
          if (osvi.dwBuildNumber >= 22000) {
269
            major = "Windows 11";
270
          } else {
271
            major = "Windows 10";
272
          }
273
        } else {
274
          if (osvi.dwBuildNumber >= 26100) {
275
            major = "Windows Server 2025";
276
          } else if (osvi.dwBuildNumber >= 20348) {
277
            major = "Windows Server 2022";
278
          } else if (osvi.dwBuildNumber >= 19042) {
279
            major = "Windows Server, version 20H2";
280
          } else if (osvi.dwBuildNumber >= 19041) {
281
            major = "Windows Server, version 2004";
282
          } else if (osvi.dwBuildNumber >= 18363) {
283
            major = "Windows Server, version 1909";
284
          } else if (osvi.dwBuildNumber >= 18362) {
285
            major = "Windows Server, version 1903";
286
          } else if (osvi.dwBuildNumber >= 17763) {
287
            // could also be Windows Server, version 1809, but there's no easy way to tell
288
            major = "Windows Server 2019";
289
          } else if (osvi.dwBuildNumber >= 17134) {
290
            major = "Windows Server, version 1803";
291
          } else if (osvi.dwBuildNumber >= 16299) {
292
            major = "Windows Server, version 1709";
293
          } else {
294
            major = "Windows Server 2016";
295
          }
296
        }
297
      }
298
    }
299
  } else if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 6) {
300
    if (osvi.dwMajorVersion == 6) {
301
      ZEND_ASSERT(osvi.dwMinorVersion >= 2);
302
      if (osvi.dwMinorVersion == 2) {
303
        /* could be Windows 8/Windows Server 2012, could be Windows 8.1/Windows Server 2012 R2 */
304
        /* XXX and one more X - the above comment is true if no manifest is used for two cases:
305
          - if the PHP build doesn't use the correct manifest
306
          - if PHP DLL loaded under some binary that doesn't use the correct manifest
307
308
          So keep the handling here as is for now, even if we know 6.2 is win8 and nothing else, and think about an improvement. */
309
        OSVERSIONINFOEX osvi81;
310
        DWORDLONG dwlConditionMask = 0;
311
        int op = VER_GREATER_EQUAL;
312
313
        ZeroMemory(&osvi81, sizeof(OSVERSIONINFOEX));
314
        osvi81.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
315
        osvi81.dwMajorVersion = 6;
316
        osvi81.dwMinorVersion = 3;
317
        osvi81.wServicePackMajor = 0;
318
319
        VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
320
        VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
321
        VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, op);
322
323
        if (VerifyVersionInfo(&osvi81,
324
          VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
325
          dwlConditionMask)) {
326
          osvi.dwMinorVersion = 3; /* Windows 8.1/Windows Server 2012 R2 */
327
          if (osvi.wProductType == VER_NT_WORKSTATION)  {
328
            major = "Windows 8.1";
329
          } else {
330
            major = "Windows Server 2012 R2";
331
          }
332
        } else {
333
          if (osvi.wProductType == VER_NT_WORKSTATION)  {
334
            major = "Windows 8";
335
          } else {
336
            major = "Windows Server 2012";
337
          }
338
        }
339
      } else if (osvi.dwMinorVersion == 3) {
340
        if (osvi.wProductType == VER_NT_WORKSTATION)  {
341
          major = "Windows 8.1";
342
        } else {
343
          major = "Windows Server 2012 R2";
344
        }
345
      } else {
346
        major = "Unknown Windows version";
347
      }
348
349
      /* No return value check, as it can only fail if the input parameters are broken (which we manually supply) */
350
      GetProductInfo(6, 0, 0, 0, &dwType);
351
352
      switch (dwType) {
353
        case PRODUCT_ULTIMATE:
354
          sub = "Ultimate Edition";
355
          break;
356
        case PRODUCT_HOME_BASIC:
357
          sub = "Home Basic Edition";
358
          break;
359
        case PRODUCT_HOME_PREMIUM:
360
          sub = "Home Premium Edition";
361
          break;
362
        case PRODUCT_ENTERPRISE:
363
          sub = "Enterprise Edition";
364
          break;
365
        case PRODUCT_HOME_BASIC_N:
366
          sub = "Home Basic N Edition";
367
          break;
368
        case PRODUCT_BUSINESS:
369
          if ((osvi.dwMajorVersion > 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion > 0)) {
370
            sub = "Professional Edition";
371
          } else {
372
            sub = "Business Edition";
373
          }
374
          break;
375
        case PRODUCT_STANDARD_SERVER:
376
          sub = "Standard Edition";
377
          break;
378
        case PRODUCT_DATACENTER_SERVER:
379
          sub = "Datacenter Edition";
380
          break;
381
        case PRODUCT_SMALLBUSINESS_SERVER:
382
          sub = "Small Business Server";
383
          break;
384
        case PRODUCT_ENTERPRISE_SERVER:
385
          sub = "Enterprise Edition";
386
          break;
387
        case PRODUCT_STARTER:
388
          if ((osvi.dwMajorVersion > 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion > 0)) {
389
            sub = "Starter N Edition";
390
          } else {
391
              sub = "Starter Edition";
392
          }
393
          break;
394
        case PRODUCT_DATACENTER_SERVER_CORE:
395
          sub = "Datacenter Edition (core installation)";
396
          break;
397
        case PRODUCT_STANDARD_SERVER_CORE:
398
          sub = "Standard Edition (core installation)";
399
          break;
400
        case PRODUCT_ENTERPRISE_SERVER_CORE:
401
          sub = "Enterprise Edition (core installation)";
402
          break;
403
        case PRODUCT_ENTERPRISE_SERVER_IA64:
404
          sub = "Enterprise Edition for Itanium-based Systems";
405
          break;
406
        case PRODUCT_BUSINESS_N:
407
          if ((osvi.dwMajorVersion > 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion > 0)) {
408
            sub = "Professional N Edition";
409
          } else {
410
            sub = "Business N Edition";
411
          }
412
          break;
413
        case PRODUCT_WEB_SERVER:
414
          sub = "Web Server Edition";
415
          break;
416
        case PRODUCT_CLUSTER_SERVER:
417
          sub = "HPC Edition";
418
          break;
419
        case PRODUCT_HOME_SERVER:
420
          sub = "Storage Server Essentials Edition";
421
          break;
422
        case PRODUCT_STORAGE_EXPRESS_SERVER:
423
          sub = "Storage Server Express Edition";
424
          break;
425
        case PRODUCT_STORAGE_STANDARD_SERVER:
426
          sub = "Storage Server Standard Edition";
427
          break;
428
        case PRODUCT_STORAGE_WORKGROUP_SERVER:
429
          sub = "Storage Server Workgroup Edition";
430
          break;
431
        case PRODUCT_STORAGE_ENTERPRISE_SERVER:
432
          sub = "Storage Server Enterprise Edition";
433
          break;
434
        case PRODUCT_SERVER_FOR_SMALLBUSINESS:
435
          sub = "Essential Server Solutions Edition";
436
          break;
437
        case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
438
          sub = "Small Business Server Premium Edition";
439
          break;
440
        case PRODUCT_HOME_PREMIUM_N:
441
          sub = "Home Premium N Edition";
442
          break;
443
        case PRODUCT_ENTERPRISE_N:
444
          sub = "Enterprise N Edition";
445
          break;
446
        case PRODUCT_ULTIMATE_N:
447
          sub = "Ultimate N Edition";
448
          break;
449
        case PRODUCT_WEB_SERVER_CORE:
450
          sub = "Web Server Edition (core installation)";
451
          break;
452
        case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
453
          sub = "Essential Business Server Management Server Edition";
454
          break;
455
        case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
456
          sub = "Essential Business Server Management Security Edition";
457
          break;
458
        case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
459
          sub = "Essential Business Server Management Messaging Edition";
460
          break;
461
        case PRODUCT_SERVER_FOUNDATION:
462
          sub = "Foundation Edition";
463
          break;
464
        case PRODUCT_HOME_PREMIUM_SERVER:
465
          sub = "Home Server 2011 Edition";
466
          break;
467
        case PRODUCT_SERVER_FOR_SMALLBUSINESS_V:
468
          sub = "Essential Server Solutions Edition (without Hyper-V)";
469
          break;
470
        case PRODUCT_STANDARD_SERVER_V:
471
          sub = "Standard Edition (without Hyper-V)";
472
          break;
473
        case PRODUCT_DATACENTER_SERVER_V:
474
          sub = "Datacenter Edition (without Hyper-V)";
475
          break;
476
        case PRODUCT_ENTERPRISE_SERVER_V:
477
          sub = "Enterprise Edition (without Hyper-V)";
478
          break;
479
        case PRODUCT_DATACENTER_SERVER_CORE_V:
480
          sub = "Datacenter Edition (core installation, without Hyper-V)";
481
          break;
482
        case PRODUCT_STANDARD_SERVER_CORE_V:
483
          sub = "Standard Edition (core installation, without Hyper-V)";
484
          break;
485
        case PRODUCT_ENTERPRISE_SERVER_CORE_V:
486
          sub = "Enterprise Edition (core installation, without Hyper-V)";
487
          break;
488
        case PRODUCT_HYPERV:
489
          sub = "Hyper-V Server";
490
          break;
491
        case PRODUCT_STORAGE_EXPRESS_SERVER_CORE:
492
          sub = "Storage Server Express Edition (core installation)";
493
          break;
494
        case PRODUCT_STORAGE_STANDARD_SERVER_CORE:
495
          sub = "Storage Server Standard Edition (core installation)";
496
          break;
497
        case PRODUCT_STORAGE_WORKGROUP_SERVER_CORE:
498
          sub = "Storage Server Workgroup Edition (core installation)";
499
          break;
500
        case PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE:
501
          sub = "Storage Server Enterprise Edition (core installation)";
502
          break;
503
        case PRODUCT_STARTER_N:
504
          sub = "Starter N Edition";
505
          break;
506
        case PRODUCT_PROFESSIONAL:
507
          sub = "Professional Edition";
508
          break;
509
        case PRODUCT_PROFESSIONAL_N:
510
          sub = "Professional N Edition";
511
          break;
512
        case PRODUCT_SB_SOLUTION_SERVER:
513
          sub = "Small Business Server 2011 Essentials Edition";
514
          break;
515
        case PRODUCT_SERVER_FOR_SB_SOLUTIONS:
516
          sub = "Server For SB Solutions Edition";
517
          break;
518
        case PRODUCT_STANDARD_SERVER_SOLUTIONS:
519
          sub = "Solutions Premium Edition";
520
          break;
521
        case PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE:
522
          sub = "Solutions Premium Edition (core installation)";
523
          break;
524
        case PRODUCT_SB_SOLUTION_SERVER_EM:
525
          sub = "Server For SB Solutions EM Edition";
526
          break;
527
        case PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM:
528
          sub = "Server For SB Solutions EM Edition";
529
          break;
530
        case PRODUCT_SOLUTION_EMBEDDEDSERVER:
531
          sub = "MultiPoint Server Edition";
532
          break;
533
        case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT:
534
          sub = "Essential Server Solution Management Edition";
535
          break;
536
        case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL:
537
          sub = "Essential Server Solution Additional Edition";
538
          break;
539
        case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC:
540
          sub = "Essential Server Solution Management SVC Edition";
541
          break;
542
        case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC:
543
          sub = "Essential Server Solution Additional SVC Edition";
544
          break;
545
        case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE:
546
          sub = "Small Business Server Premium Edition (core installation)";
547
          break;
548
        case PRODUCT_CLUSTER_SERVER_V:
549
          sub = "Hyper Core V Edition";
550
          break;
551
        case PRODUCT_STARTER_E:
552
          sub = "Hyper Core V Edition";
553
          break;
554
        case PRODUCT_ENTERPRISE_EVALUATION:
555
          sub = "Enterprise Edition (evaluation installation)";
556
          break;
557
        case PRODUCT_MULTIPOINT_STANDARD_SERVER:
558
          sub = "MultiPoint Server Standard Edition (full installation)";
559
          break;
560
        case PRODUCT_MULTIPOINT_PREMIUM_SERVER:
561
          sub = "MultiPoint Server Premium Edition (full installation)";
562
          break;
563
        case PRODUCT_STANDARD_EVALUATION_SERVER:
564
          sub = "Standard Edition (evaluation installation)";
565
          break;
566
        case PRODUCT_DATACENTER_EVALUATION_SERVER:
567
          sub = "Datacenter Edition (evaluation installation)";
568
          break;
569
        case PRODUCT_ENTERPRISE_N_EVALUATION:
570
          sub = "Enterprise N Edition (evaluation installation)";
571
          break;
572
        case PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER:
573
          sub = "Storage Server Workgroup Edition (evaluation installation)";
574
          break;
575
        case PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER:
576
          sub = "Storage Server Standard Edition (evaluation installation)";
577
          break;
578
        case PRODUCT_CORE_N:
579
          sub = "Windows 8 N Edition";
580
          break;
581
        case PRODUCT_CORE_COUNTRYSPECIFIC:
582
          sub = "Windows 8 China Edition";
583
          break;
584
        case PRODUCT_CORE_SINGLELANGUAGE:
585
          sub = "Windows 8 Single Language Edition";
586
          break;
587
        case PRODUCT_CORE:
588
          sub = "Windows 8 Edition";
589
          break;
590
        case PRODUCT_PROFESSIONAL_WMC:
591
          sub = "Professional with Media Center Edition";
592
          break;
593
      }
594
    }
595
  } else {
596
    ZEND_UNREACHABLE();
597
  }
598
599
  char *retval;
600
  spprintf(&retval, 0, "%s%s%s%s%s", major, sub?" ":"", sub?sub:"", osvi.szCSDVersion[0] != '\0'?" ":"", osvi.szCSDVersion);
601
  return retval;
602
}
603
/* }}}  */
604
605
/* {{{  */
606
static void php_get_windows_cpu(char *buf, size_t bufsize)
607
{
608
  SYSTEM_INFO SysInfo;
609
  GetSystemInfo(&SysInfo);
610
  switch (SysInfo.wProcessorArchitecture) {
611
    case PROCESSOR_ARCHITECTURE_INTEL :
612
      snprintf(buf, bufsize, "i%lu", SysInfo.dwProcessorType);
613
      break;
614
    case PROCESSOR_ARCHITECTURE_MIPS :
615
      snprintf(buf, bufsize, "MIPS R%d000", SysInfo.wProcessorLevel);
616
      break;
617
    case PROCESSOR_ARCHITECTURE_ALPHA :
618
      snprintf(buf, bufsize, "Alpha %d", SysInfo.wProcessorLevel);
619
      break;
620
    case PROCESSOR_ARCHITECTURE_PPC :
621
      snprintf(buf, bufsize, "PPC 6%02d", SysInfo.wProcessorLevel);
622
      break;
623
    case PROCESSOR_ARCHITECTURE_IA64 :
624
      snprintf(buf, bufsize,  "IA64");
625
      break;
626
#if defined(PROCESSOR_ARCHITECTURE_IA32_ON_WIN64)
627
    case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 :
628
      snprintf(buf, bufsize, "IA32");
629
      break;
630
#endif
631
#if defined(PROCESSOR_ARCHITECTURE_AMD64)
632
    case PROCESSOR_ARCHITECTURE_AMD64 :
633
      snprintf(buf, bufsize, "AMD64");
634
      break;
635
#endif
636
#if defined(PROCESSOR_ARCHITECTURE_ARM64)
637
    case PROCESSOR_ARCHITECTURE_ARM64 :
638
      snprintf(buf, bufsize, "ARM64");
639
      break;
640
#endif
641
    case PROCESSOR_ARCHITECTURE_UNKNOWN :
642
    default:
643
      snprintf(buf, bufsize, "Unknown");
644
      break;
645
  }
646
}
647
/* }}}  */
648
#endif
649
650
11
static inline bool php_is_valid_uname_mode(char mode) {
651
11
  return mode == 'a' || mode == 'm' || mode == 'n' || mode == 'r' || mode == 's' || mode == 'v';
652
11
}
653
654
/* {{{ php_get_uname */
655
PHPAPI zend_string *php_get_uname(char mode)
656
11
{
657
11
  char *php_uname;
658
659
11
  ZEND_ASSERT(php_is_valid_uname_mode(mode));
660
#ifdef PHP_WIN32
661
  char tmp_uname[256];
662
  OSVERSIONINFOEX osvi = EG(windows_version_info);
663
  DWORD dwWindowsMajorVersion = osvi.dwMajorVersion;
664
  DWORD dwWindowsMinorVersion = osvi.dwMinorVersion;
665
  DWORD dwBuild = osvi.dwBuildNumber;
666
  DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
667
  char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
668
669
  GetComputerName(ComputerName, &dwSize);
670
671
  if (mode == 's') {
672
    php_uname = "Windows NT";
673
  } else if (mode == 'r') {
674
    return strpprintf(0, "%lu.%lu", dwWindowsMajorVersion, dwWindowsMinorVersion);
675
  } else if (mode == 'n') {
676
    php_uname = ComputerName;
677
  } else if (mode == 'v') {
678
    char *winver = php_get_windows_name();
679
680
    ZEND_ASSERT(winver != NULL);
681
682
    zend_string *build_with_version = strpprintf(0, "build %lu (%s)", dwBuild, winver);
683
    efree(winver);
684
    return build_with_version;
685
  } else if (mode == 'm') {
686
    php_get_windows_cpu(tmp_uname, sizeof(tmp_uname));
687
    php_uname = tmp_uname;
688
  } else { /* assume mode == 'a' */
689
    char *winver = php_get_windows_name();
690
    char wincpu[20];
691
692
    ZEND_ASSERT(winver != NULL);
693
694
    php_get_windows_cpu(wincpu, sizeof(wincpu));
695
696
    /* Windows "version" 6.2 could be Windows 8/Windows Server 2012, but also Windows 8.1/Windows Server 2012 R2 */
697
    if (dwWindowsMajorVersion == 6 && dwWindowsMinorVersion == 2) {
698
      if (strncmp(winver, "Windows 8.1", strlen("Windows 8.1")) == 0 || strncmp(winver, "Windows Server 2012 R2", strlen("Windows Server 2012 R2")) == 0) {
699
        dwWindowsMinorVersion = 3;
700
      }
701
    }
702
703
    zend_string *build_with_all_info = strpprintf(0, "%s %s %lu.%lu build %lu (%s) %s",
704
      "Windows NT", ComputerName, dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild,
705
      winver ? winver: "unknown", wincpu);
706
    efree(winver);
707
    return build_with_all_info;
708
  }
709
#else
710
11
#ifdef HAVE_SYS_UTSNAME_H
711
11
  struct utsname buf;
712
11
  if (uname((struct utsname *)&buf) == -1) {
713
0
    php_uname = PHP_UNAME;
714
11
  } else {
715
11
    if (mode == 's') {
716
0
      php_uname = buf.sysname;
717
11
    } else if (mode == 'r') {
718
0
      php_uname = buf.release;
719
11
    } else if (mode == 'n') {
720
0
      php_uname = buf.nodename;
721
11
    } else if (mode == 'v') {
722
0
      php_uname = buf.version;
723
11
    } else if (mode == 'm') {
724
0
      php_uname = buf.machine;
725
11
    } else { /* assume mode == 'a' */
726
11
      return strpprintf(0, "%s %s %s %s %s", buf.sysname, buf.nodename, buf.release, buf.version, buf.machine);
727
11
    }
728
11
  }
729
#else
730
  php_uname = PHP_UNAME;
731
#endif
732
0
#endif
733
0
  return zend_string_init(php_uname, strlen(php_uname), 0);
734
11
}
735
/* }}} */
736
737
/* {{{ php_print_info_htmlhead */
738
PHPAPI ZEND_COLD void php_print_info_htmlhead(void)
739
0
{
740
0
  php_info_print("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\">\n");
741
0
  php_info_print("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
742
0
  php_info_print("<head>\n");
743
0
  php_info_print_style();
744
0
  php_info_printf("<title>PHP %s - phpinfo()</title>", PHP_VERSION);
745
0
  php_info_print("<meta name=\"ROBOTS\" content=\"NOINDEX,NOFOLLOW,NOARCHIVE\" />");
746
0
  php_info_print("</head>\n");
747
0
  php_info_print("<body><div class=\"center\">\n");
748
0
}
749
/* }}} */
750
751
/* {{{ module_name_cmp */
752
static int module_name_cmp(Bucket *f, Bucket *s)
753
319
{
754
319
  return strcasecmp(((zend_module_entry *)Z_PTR(f->val))->name,
755
319
          ((zend_module_entry *)Z_PTR(s->val))->name);
756
319
}
757
/* }}} */
758
759
/* {{{ php_print_info */
760
PHPAPI ZEND_COLD void php_print_info(int flag)
761
11
{
762
11
  char **env, *tmp1, *tmp2;
763
11
  zend_string *php_uname;
764
765
11
  if (!sapi_module.phpinfo_as_text) {
766
0
    php_print_info_htmlhead();
767
11
  } else {
768
11
    php_info_print("phpinfo()\n");
769
11
  }
770
771
11
  if (flag & PHP_INFO_GENERAL) {
772
11
    const char *zend_version = get_zend_version();
773
11
    char temp_api[10];
774
775
11
    php_uname = php_get_uname('a');
776
777
11
    if (!sapi_module.phpinfo_as_text) {
778
0
      php_info_print_box_start(1);
779
0
    }
780
781
11
    if (!sapi_module.phpinfo_as_text) {
782
0
          time_t the_time;
783
0
          struct tm *ta, tmbuf;
784
785
0
          the_time = time(NULL);
786
0
          ta = php_localtime_r(&the_time, &tmbuf);
787
788
0
      php_info_print("<a href=\"https://www.php.net/\"><img src=\"");
789
0
          if (ta && (ta->tm_mon==3) && (ta->tm_mday==1)) {
790
0
            php_info_print(PHP_EGG_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
791
0
          } else {
792
0
            php_info_print(PHP_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
793
0
      }
794
0
    }
795
796
11
    if (!sapi_module.phpinfo_as_text) {
797
0
      php_info_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
798
11
    } else {
799
11
      php_info_print_table_row(2, "PHP Version", PHP_VERSION);
800
11
    }
801
11
    php_info_print_box_end();
802
11
    php_info_print_table_start();
803
11
    php_info_print_table_row(2, "System", ZSTR_VAL(php_uname));
804
11
    php_info_print_table_row(2, "Build Date", php_build_date);
805
11
#ifdef PHP_BUILD_SYSTEM
806
11
    php_info_print_table_row(2, "Build System", PHP_BUILD_SYSTEM);
807
11
#endif
808
11
    if (php_build_provider()) {
809
0
      php_info_print_table_row(2, "Build Provider", php_build_provider());
810
0
    }
811
#ifdef PHP_BUILD_COMPILER
812
    php_info_print_table_row(2, "Compiler", PHP_BUILD_COMPILER);
813
#endif
814
#ifdef PHP_BUILD_ARCH
815
    php_info_print_table_row(2, "Architecture", PHP_BUILD_ARCH);
816
#endif
817
11
#ifdef CONFIGURE_COMMAND
818
11
    php_info_print_table_row(2, "Configure Command", CONFIGURE_COMMAND );
819
11
#endif
820
821
11
    if (sapi_module.pretty_name) {
822
11
      php_info_print_table_row(2, "Server API", sapi_module.pretty_name );
823
11
    }
824
825
#ifdef VIRTUAL_DIR
826
    php_info_print_table_row(2, "Virtual Directory Support", "enabled" );
827
#else
828
11
    php_info_print_table_row(2, "Virtual Directory Support", "disabled" );
829
11
#endif
830
831
11
    php_info_print_table_row(2, "Configuration File (php.ini) Path", PHP_CONFIG_FILE_PATH);
832
11
    php_info_print_table_row(2, "Loaded Configuration File", php_ini_opened_path ? php_ini_opened_path : "(none)");
833
11
    php_info_print_table_row(2, "Scan this dir for additional .ini files", php_ini_scanned_path ? php_ini_scanned_path : "(none)");
834
11
    php_info_print_table_row(2, "Additional .ini files parsed", php_ini_scanned_files ? php_ini_scanned_files : "(none)");
835
836
11
    snprintf(temp_api, sizeof(temp_api), "%d", PHP_API_VERSION);
837
11
    php_info_print_table_row(2, "PHP API", temp_api);
838
839
11
    snprintf(temp_api, sizeof(temp_api), "%d", ZEND_MODULE_API_NO);
840
11
    php_info_print_table_row(2, "PHP Extension", temp_api);
841
842
11
    snprintf(temp_api, sizeof(temp_api), "%d", ZEND_EXTENSION_API_NO);
843
11
    php_info_print_table_row(2, "Zend Extension", temp_api);
844
845
11
    php_info_print_table_row(2, "Zend Extension Build", ZEND_EXTENSION_BUILD_ID);
846
11
    php_info_print_table_row(2, "PHP Extension Build", ZEND_MODULE_BUILD_ID);
847
848
11
    snprintf(temp_api, sizeof(temp_api), "%d bits", SIZEOF_ZEND_LONG * 8);
849
11
    php_info_print_table_row(2, "PHP Integer Size", temp_api);
850
851
11
#if ZEND_DEBUG
852
11
    php_info_print_table_row(2, "Debug Build", "yes" );
853
#else
854
    php_info_print_table_row(2, "Debug Build", "no" );
855
#endif
856
857
#ifdef ZTS
858
    php_info_print_table_row(2, "Thread Safety", "enabled" );
859
    php_info_print_table_row(2, "Thread API", tsrm_api_name() );
860
#else
861
11
    php_info_print_table_row(2, "Thread Safety", "disabled" );
862
11
#endif
863
864
11
#ifdef ZEND_SIGNALS
865
11
    php_info_print_table_row(2, "Zend Signal Handling", "enabled" );
866
#else
867
    php_info_print_table_row(2, "Zend Signal Handling", "disabled" );
868
#endif
869
870
11
    php_info_print_table_row(2, "Zend Memory Manager", is_zend_mm() ? "enabled" : "disabled" );
871
872
11
    {
873
11
      const zend_multibyte_functions *functions = zend_multibyte_get_functions();
874
11
      char *descr;
875
11
      if (functions) {
876
0
        spprintf(&descr, 0, "provided by %s", functions->provider_name);
877
11
      } else {
878
11
        descr = estrdup("disabled");
879
11
      }
880
11
      php_info_print_table_row(2, "Zend Multibyte Support", descr);
881
11
      efree(descr);
882
11
    }
883
884
#ifdef ZEND_MAX_EXECUTION_TIMERS
885
    php_info_print_table_row(2, "Zend Max Execution Timers", "enabled" );
886
#else
887
11
    php_info_print_table_row(2, "Zend Max Execution Timers", "disabled" );
888
11
#endif
889
890
11
#ifdef HAVE_IPV6
891
11
    php_info_print_table_row(2, "IPv6 Support", "enabled" );
892
#else
893
    php_info_print_table_row(2, "IPv6 Support", "disabled" );
894
#endif
895
896
#ifdef HAVE_DTRACE
897
    php_info_print_table_row(2, "DTrace Support", (zend_dtrace_enabled ? "enabled" : "available, disabled"));
898
#else
899
11
    php_info_print_table_row(2, "DTrace Support", "disabled" );
900
11
#endif
901
902
11
    php_info_print_stream_hash("PHP Streams",  php_stream_get_url_stream_wrappers_hash());
903
11
    php_info_print_stream_hash("Stream Socket Transports", php_stream_xport_get_hash());
904
11
    php_info_print_stream_hash("Stream Filters", php_get_stream_filters_hash());
905
906
11
    php_info_print_table_end();
907
908
    /* Zend Engine */
909
11
    php_info_print_box_start(0);
910
11
    if (!sapi_module.phpinfo_as_text) {
911
0
      php_info_print("<a href=\"https://www.zend.com/\"><img src=\"");
912
0
      php_info_print(ZEND_LOGO_DATA_URI "\" alt=\"Zend logo\" /></a>\n");
913
0
    }
914
11
    php_info_print("This program makes use of the Zend Scripting Language Engine:");
915
11
    php_info_print(!sapi_module.phpinfo_as_text?"<br />":"\n");
916
11
    if (sapi_module.phpinfo_as_text) {
917
11
      php_info_print(zend_version);
918
11
    } else {
919
0
      zend_html_puts(zend_version, strlen(zend_version));
920
0
    }
921
11
    php_info_print_box_end();
922
11
    zend_string_free(php_uname);
923
11
  }
924
925
11
  zend_ini_sort_entries();
926
927
11
  if (flag & PHP_INFO_CONFIGURATION) {
928
11
    php_info_print_hr();
929
11
    if (!sapi_module.phpinfo_as_text) {
930
0
      php_info_print("<h1>Configuration</h1>\n");
931
11
    } else {
932
11
      SECTION("Configuration");
933
11
    }
934
11
    if (!(flag & PHP_INFO_MODULES)) {
935
0
      SECTION("PHP Core");
936
0
      display_ini_entries(NULL);
937
0
    }
938
11
  }
939
940
11
  if (flag & PHP_INFO_MODULES) {
941
11
    HashTable sorted_registry;
942
11
    zend_module_entry *module;
943
944
11
    zend_hash_init(&sorted_registry, zend_hash_num_elements(&module_registry), NULL, NULL, 1);
945
11
    zend_hash_copy(&sorted_registry, &module_registry, NULL);
946
11
    zend_hash_sort(&sorted_registry, module_name_cmp, 0);
947
948
308
    ZEND_HASH_MAP_FOREACH_PTR(&sorted_registry, module) {
949
308
      if (module->info_func || module->version) {
950
143
        php_info_print_module(module);
951
143
      }
952
308
    } ZEND_HASH_FOREACH_END();
953
954
11
    SECTION("Additional Modules");
955
11
    php_info_print_table_start();
956
11
    php_info_print_table_header(1, "Module Name");
957
308
    ZEND_HASH_MAP_FOREACH_PTR(&sorted_registry, module) {
958
308
      if (!module->info_func && !module->version) {
959
0
        php_info_print_module(module);
960
0
      }
961
308
    } ZEND_HASH_FOREACH_END();
962
11
    php_info_print_table_end();
963
964
11
    zend_hash_destroy(&sorted_registry);
965
11
  }
966
967
11
  if (flag & PHP_INFO_ENVIRONMENT) {
968
11
    SECTION("Environment");
969
11
    php_info_print_table_start();
970
11
    php_info_print_table_header(2, "Variable", "Value");
971
11
    tsrm_env_lock();
972
418
    for (env=environ; env!=NULL && *env !=NULL; env++) {
973
407
      tmp1 = estrdup(*env);
974
407
      if (!(tmp2=strchr(tmp1,'='))) { /* malformed entry? */
975
0
        efree(tmp1);
976
0
        continue;
977
0
      }
978
407
      *tmp2 = 0;
979
407
      tmp2++;
980
407
      php_info_print_table_row(2, tmp1, tmp2);
981
407
      efree(tmp1);
982
407
    }
983
11
    tsrm_env_unlock();
984
11
    php_info_print_table_end();
985
11
  }
986
987
11
  if (flag & PHP_INFO_VARIABLES) {
988
11
    zval *data;
989
990
11
    SECTION("PHP Variables");
991
992
11
    php_info_print_table_start();
993
11
    php_info_print_table_header(2, "Variable", "Value");
994
11
    if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
995
0
      php_info_print_table_row(2, "PHP_SELF", Z_STRVAL_P(data));
996
0
    }
997
11
    if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
998
0
      php_info_print_table_row(2, "PHP_AUTH_TYPE", Z_STRVAL_P(data));
999
0
    }
1000
11
    if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
1001
0
      php_info_print_table_row(2, "PHP_AUTH_USER", Z_STRVAL_P(data));
1002
0
    }
1003
11
    if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
1004
0
      php_info_print_table_row(2, "PHP_AUTH_PW", Z_STRVAL_P(data));
1005
0
    }
1006
11
    php_print_gpcse_array(ZEND_STRL("_REQUEST"));
1007
11
    php_print_gpcse_array(ZEND_STRL("_GET"));
1008
11
    php_print_gpcse_array(ZEND_STRL("_POST"));
1009
11
    php_print_gpcse_array(ZEND_STRL("_FILES"));
1010
11
    php_print_gpcse_array(ZEND_STRL("_COOKIE"));
1011
11
    php_print_gpcse_array(ZEND_STRL("_SERVER"));
1012
11
    php_print_gpcse_array(ZEND_STRL("_ENV"));
1013
11
    php_info_print_table_end();
1014
11
  }
1015
1016
1017
11
  if (flag & PHP_INFO_CREDITS) {
1018
11
    php_info_print_hr();
1019
11
    php_print_credits(PHP_CREDITS_ALL & ~PHP_CREDITS_FULLPAGE);
1020
11
  }
1021
1022
11
  if (flag & PHP_INFO_LICENSE) {
1023
11
    if (!sapi_module.phpinfo_as_text) {
1024
0
      SECTION("PHP License");
1025
0
      php_info_print_box_start(0);
1026
0
      php_info_print("<p>\n");
1027
0
      php_info_print("This program is free software; you can redistribute it and/or modify ");
1028
0
      php_info_print("it under the terms of the PHP License as published by the PHP Group ");
1029
0
      php_info_print("and included in the distribution in the file:  LICENSE\n");
1030
0
      php_info_print("</p>\n");
1031
0
      php_info_print("<p>");
1032
0
      php_info_print("This program is distributed in the hope that it will be useful, ");
1033
0
      php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of ");
1034
0
      php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
1035
0
      php_info_print("</p>\n");
1036
0
      php_info_print("<p>");
1037
0
      php_info_print("If you did not receive a copy of the PHP license, or have any questions about ");
1038
0
      php_info_print("PHP licensing, please contact license@php.net.\n");
1039
0
      php_info_print("</p>\n");
1040
0
      php_info_print_box_end();
1041
11
    } else {
1042
11
      php_info_print("\nPHP License\n");
1043
11
      php_info_print("This program is free software; you can redistribute it and/or modify\n");
1044
11
      php_info_print("it under the terms of the PHP License as published by the PHP Group\n");
1045
11
      php_info_print("and included in the distribution in the file:  LICENSE\n");
1046
11
      php_info_print("\n");
1047
11
      php_info_print("This program is distributed in the hope that it will be useful,\n");
1048
11
      php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
1049
11
      php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
1050
11
      php_info_print("\n");
1051
11
      php_info_print("If you did not receive a copy of the PHP license, or have any\n");
1052
11
      php_info_print("questions about PHP licensing, please contact license@php.net.\n");
1053
11
    }
1054
11
  }
1055
1056
11
  if (!sapi_module.phpinfo_as_text) {
1057
0
    php_info_print("</div></body></html>");
1058
0
  }
1059
11
}
1060
/* }}} */
1061
1062
PHPAPI ZEND_COLD void php_info_print_table_start(void) /* {{{ */
1063
649
{
1064
649
  if (!sapi_module.phpinfo_as_text) {
1065
0
    php_info_print("<table>\n");
1066
649
  } else {
1067
649
    php_info_print("\n");
1068
649
  }
1069
649
}
1070
/* }}} */
1071
1072
PHPAPI ZEND_COLD void php_info_print_table_end(void) /* {{{ */
1073
660
{
1074
660
  if (!sapi_module.phpinfo_as_text) {
1075
0
    php_info_print("</table>\n");
1076
0
  }
1077
1078
660
}
1079
/* }}} */
1080
1081
PHPAPI ZEND_COLD void php_info_print_box_start(int flag) /* {{{ */
1082
11
{
1083
11
  php_info_print_table_start();
1084
11
  if (flag) {
1085
0
    if (!sapi_module.phpinfo_as_text) {
1086
0
      php_info_print("<tr class=\"h\"><td>\n");
1087
0
    }
1088
11
  } else {
1089
11
    if (!sapi_module.phpinfo_as_text) {
1090
0
      php_info_print("<tr class=\"v\"><td>\n");
1091
11
    } else {
1092
11
      php_info_print("\n");
1093
11
    }
1094
11
  }
1095
11
}
1096
/* }}} */
1097
1098
PHPAPI ZEND_COLD void php_info_print_box_end(void) /* {{{ */
1099
22
{
1100
22
  if (!sapi_module.phpinfo_as_text) {
1101
0
    php_info_print("</td></tr>\n");
1102
0
  }
1103
22
  php_info_print_table_end();
1104
22
}
1105
/* }}} */
1106
1107
PHPAPI ZEND_COLD void php_info_print_hr(void) /* {{{ */
1108
22
{
1109
22
  if (!sapi_module.phpinfo_as_text) {
1110
0
    php_info_print("<hr />\n");
1111
22
  } else {
1112
22
    php_info_print("\n\n _______________________________________________________________________\n\n");
1113
22
  }
1114
22
}
1115
/* }}} */
1116
1117
PHPAPI ZEND_COLD void php_info_print_table_colspan_header(int num_cols, const char *header) /* {{{ */
1118
55
{
1119
55
  int spaces;
1120
1121
55
  if (!sapi_module.phpinfo_as_text) {
1122
0
    php_info_printf("<tr class=\"h\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header );
1123
55
  } else {
1124
55
    spaces = (int)(74 - strlen(header));
1125
55
    php_info_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " ");
1126
55
  }
1127
55
}
1128
/* }}} */
1129
1130
/* {{{ php_info_print_table_header */
1131
PHPAPI ZEND_COLD void php_info_print_table_header(int num_cols, ...)
1132
407
{
1133
407
  int i;
1134
407
  va_list row_elements;
1135
407
  char *row_element;
1136
1137
407
  va_start(row_elements, num_cols);
1138
407
  if (!sapi_module.phpinfo_as_text) {
1139
0
    php_info_print("<tr class=\"h\">");
1140
0
  }
1141
1.00k
  for (i=0; i<num_cols; i++) {
1142
594
    row_element = va_arg(row_elements, char *);
1143
594
    if (!row_element || !*row_element) {
1144
0
      row_element = " ";
1145
0
    }
1146
594
    if (!sapi_module.phpinfo_as_text) {
1147
0
      php_info_print("<th>");
1148
0
      php_info_print(row_element);
1149
0
      php_info_print("</th>");
1150
594
    } else {
1151
594
      php_info_print(row_element);
1152
594
      if (i < num_cols-1) {
1153
187
        php_info_print(" => ");
1154
407
      } else {
1155
407
        php_info_print("\n");
1156
407
      }
1157
594
    }
1158
594
  }
1159
407
  if (!sapi_module.phpinfo_as_text) {
1160
0
    php_info_print("</tr>\n");
1161
0
  }
1162
1163
407
  va_end(row_elements);
1164
407
}
1165
/* }}} */
1166
1167
/* {{{ php_info_print_table_row_internal */
1168
static ZEND_COLD void php_info_print_table_row_internal(int num_cols,
1169
    const char *value_class, va_list row_elements)
1170
2.33k
{
1171
2.33k
  int i;
1172
2.33k
  char *row_element;
1173
1174
2.33k
  if (!sapi_module.phpinfo_as_text) {
1175
0
    php_info_print("<tr>");
1176
0
  }
1177
6.96k
  for (i=0; i<num_cols; i++) {
1178
4.63k
    if (!sapi_module.phpinfo_as_text) {
1179
0
      php_info_printf("<td class=\"%s\">",
1180
0
         (i==0 ? "e" : value_class )
1181
0
      );
1182
0
    }
1183
4.63k
    row_element = va_arg(row_elements, char *);
1184
4.63k
    if (!row_element || !*row_element) {
1185
22
      if (!sapi_module.phpinfo_as_text) {
1186
0
        php_info_print( "<i>no value</i>" );
1187
22
      } else {
1188
22
        php_info_print( " " );
1189
22
      }
1190
4.60k
    } else {
1191
4.60k
      if (!sapi_module.phpinfo_as_text) {
1192
0
        php_info_print_html_esc(row_element, strlen(row_element));
1193
4.60k
      } else {
1194
4.60k
        php_info_print(row_element);
1195
4.60k
        if (i < num_cols-1) {
1196
2.29k
          php_info_print(" => ");
1197
2.29k
        }
1198
4.60k
      }
1199
4.60k
    }
1200
4.63k
    if (!sapi_module.phpinfo_as_text) {
1201
0
      php_info_print(" </td>");
1202
4.63k
    } else if (i == (num_cols - 1)) {
1203
2.33k
      php_info_print("\n");
1204
2.33k
    }
1205
4.63k
  }
1206
2.33k
  if (!sapi_module.phpinfo_as_text) {
1207
0
    php_info_print("</tr>\n");
1208
0
  }
1209
2.33k
}
1210
/* }}} */
1211
1212
/* {{{ php_info_print_table_row */
1213
PHPAPI ZEND_COLD void php_info_print_table_row(int num_cols, ...)
1214
2.33k
{
1215
2.33k
  va_list row_elements;
1216
1217
2.33k
  va_start(row_elements, num_cols);
1218
2.33k
  php_info_print_table_row_internal(num_cols, "v", row_elements);
1219
2.33k
  va_end(row_elements);
1220
2.33k
}
1221
/* }}} */
1222
1223
/* {{{ php_info_print_table_row_ex */
1224
PHPAPI ZEND_COLD void php_info_print_table_row_ex(int num_cols, const char *value_class,
1225
    ...)
1226
0
{
1227
0
  va_list row_elements;
1228
1229
0
  va_start(row_elements, value_class);
1230
0
  php_info_print_table_row_internal(num_cols, value_class, row_elements);
1231
0
  va_end(row_elements);
1232
0
}
1233
/* }}} */
1234
1235
/* {{{ Output a page of useful information about PHP and the current request */
1236
PHP_FUNCTION(phpinfo)
1237
11
{
1238
11
  zend_long flag = PHP_INFO_ALL;
1239
1240
33
  ZEND_PARSE_PARAMETERS_START(0, 1)
1241
33
    Z_PARAM_OPTIONAL
1242
33
    Z_PARAM_LONG(flag)
1243
11
  ZEND_PARSE_PARAMETERS_END();
1244
1245
  /* Andale!  Andale!  Yee-Hah! */
1246
11
  php_output_start_default();
1247
11
  php_print_info((int)flag);
1248
11
  php_output_end();
1249
1250
11
  RETURN_TRUE;
1251
11
}
1252
1253
/* }}} */
1254
1255
/* {{{ Return the current PHP version */
1256
PHP_FUNCTION(phpversion)
1257
0
{
1258
0
  char *ext_name = NULL;
1259
0
  size_t ext_name_len = 0;
1260
1261
0
  ZEND_PARSE_PARAMETERS_START(0, 1)
1262
0
    Z_PARAM_OPTIONAL
1263
0
    Z_PARAM_STRING_OR_NULL(ext_name, ext_name_len)
1264
0
  ZEND_PARSE_PARAMETERS_END();
1265
1266
0
  if (!ext_name) {
1267
0
    RETURN_STRING(PHP_VERSION);
1268
0
  } else {
1269
0
    const char *version;
1270
0
    version = zend_get_module_version(ext_name);
1271
0
    if (version == NULL) {
1272
0
      RETURN_FALSE;
1273
0
    }
1274
0
    RETURN_STRING(version);
1275
0
  }
1276
0
}
1277
/* }}} */
1278
1279
/* {{{ Prints the list of people who've contributed to the PHP project */
1280
PHP_FUNCTION(phpcredits)
1281
0
{
1282
0
  zend_long flag = PHP_CREDITS_ALL;
1283
1284
0
  ZEND_PARSE_PARAMETERS_START(0, 1)
1285
0
    Z_PARAM_OPTIONAL
1286
0
    Z_PARAM_LONG(flag)
1287
0
  ZEND_PARSE_PARAMETERS_END();
1288
1289
0
  php_print_credits((int)flag);
1290
0
  RETURN_TRUE;
1291
0
}
1292
/* }}} */
1293
1294
/* {{{ Return the current SAPI module name */
1295
PHP_FUNCTION(php_sapi_name)
1296
9
{
1297
9
  ZEND_PARSE_PARAMETERS_NONE();
1298
1299
9
  if (sapi_module.name) {
1300
9
    RETURN_STRING(sapi_module.name);
1301
9
  } else {
1302
0
    RETURN_FALSE;
1303
0
  }
1304
9
}
1305
1306
/* }}} */
1307
1308
/* {{{ Return information about the system PHP was built on */
1309
PHP_FUNCTION(php_uname)
1310
0
{
1311
0
  char *mode_str = "a";
1312
0
  size_t modelen = sizeof("a")-1;
1313
1314
0
  ZEND_PARSE_PARAMETERS_START(0, 1)
1315
0
    Z_PARAM_OPTIONAL
1316
0
    Z_PARAM_STRING(mode_str, modelen)
1317
0
  ZEND_PARSE_PARAMETERS_END();
1318
1319
0
  if (modelen != 1) {
1320
0
    zend_argument_value_error(1, "must be a single character");
1321
0
    RETURN_THROWS();
1322
0
  }
1323
1324
0
  char mode = *mode_str;
1325
0
  if (!php_is_valid_uname_mode(mode)) {
1326
0
    zend_argument_value_error(1, "must be one of \"a\", \"m\", \"n\", \"r\", \"s\", or \"v\"");
1327
0
    RETURN_THROWS();
1328
0
  }
1329
1330
0
  RETURN_STR(php_get_uname(mode));
1331
0
}
1332
1333
/* }}} */
1334
1335
/* {{{ Return comma-separated string of .ini files parsed from the additional ini dir */
1336
PHP_FUNCTION(php_ini_scanned_files)
1337
0
{
1338
0
  ZEND_PARSE_PARAMETERS_NONE();
1339
1340
0
  if (php_ini_scanned_files) {
1341
0
    RETURN_STRING(php_ini_scanned_files);
1342
0
  } else {
1343
0
    RETURN_FALSE;
1344
0
  }
1345
0
}
1346
/* }}} */
1347
1348
/* {{{ Return the actual loaded ini filename */
1349
PHP_FUNCTION(php_ini_loaded_file)
1350
0
{
1351
0
  ZEND_PARSE_PARAMETERS_NONE();
1352
1353
0
  if (php_ini_opened_path) {
1354
0
    RETURN_STRING(php_ini_opened_path);
1355
0
  } else {
1356
0
    RETURN_FALSE;
1357
0
  }
1358
0
}
1359
/* }}} */