Thursday, January 26, 2023

acne causes

 

Causes

Risk factors for the development of acne, other than genetics, have not been conclusively identified. Possible secondary contributors include hormones, infections, diet, and stress. Studies investigating the impact of smoking on the incidence and severity of acne have been inconclusive.[2][40][41] Sunlight and cleanliness are not associated with acne.[14]

Genes

Acne appears to be highly heritable; genetics explain 81% of the variation in the population.[15] Studies performed in affected twins and first-degree relatives further demonstrate the strongly inherited nature of acne.[2][15] Acne susceptibility is likely due to the influence of multiple genes, as the disease does not follow a classic (Mendelian) inheritance pattern. These gene candidates include certain variations in tumor necrosis factor-alpha (TNF-alpha), IL-1 alpha, and CYP1A1 genes, among others.[19] The 308 G/A single nucleotide polymorphism variation in the gene for TNF is associated with an increased risk for acne.[42] Acne can be a feature of rare genetic disorders such as Apert's syndrome.[15] Severe acne may be associated with XYY syndrome.[43]

Hormones

Hormonal activity, such as occurs during menstrual cycles and puberty, may contribute to the formation of acne. During puberty, an increase in sex hormones called androgens causes the skin follicle glands to grow larger and make more oily sebum.[12] The androgen hormones testosterone, dihydrotestosterone (DHT), and dehydroepiandrosterone (DHEA) are all linked to acne. High levels of growth hormone (GH) and insulin-like growth factor 1 (IGF-1) are also associated with worsened acne.[44] Both androgens and IGF-1 seem to be essential for acne to occur, as acne does not develop in individuals with complete androgen insensitivity syndrome (CAIS) or Laron syndrome (insensitivity to GH, resulting in very low IGF-1 levels).[45][46]

Medical conditions that commonly cause a high-androgen state, such as polycystic ovary syndrome, congenital adrenal hyperplasia, and androgen-secreting tumors, can cause acne in affected individuals.[47][48] Conversely, people who lack androgenic hormones or are insensitive to the effects of androgens rarely have acne.[47] Pregnancy can increase androgen levels, and consequently, oily sebum synthesis.[48][49] Acne can be a side effect of testosterone replacement therapy or anabolic steroid use.[1][50] Over-the-counter bodybuilding and dietary supplements often contain illegally added anabolic steroids.[1][51]

acne vulgaris

 

The severity of acne vulgaris (Gr. ἀκµή, "point" + L. vulgaris, "common")[24] can be classified as mild, moderate, or severe to determine an appropriate treatment regimen.[20] There is no universally accepted scale for grading acne severity.[15] The presence of clogged skin follicles (known as comedones) limited to the face with occasional inflammatory lesions defines mild acne.[20] Moderate severity acne is said to occur when a higher number of inflammatory papules and pustules occur on the face, compared to mild cases of acne, and appear on the trunk of the body.[20] Severe acne is said to occur when nodules (the painful 'bumps' lying under the skin) are the characteristic facial lesions, and involvement of the trunk is extensive.[20][25]

Large nodules were previously called cysts. The term nodulocystic has been used in the medical literature to describe severe cases of inflammatory acne.[25] True cysts are rare in those with acne, and the term severe nodular acne is now the preferred terminology.[25]

Acne inversa (L. invertō, "upside-down") and acne rosacea (rosa, "rose-colored" + -āceus, "forming") are not forms of acne and are alternate names that respectively refer to the skin conditions hidradenitis suppurativa (HS) and rosacea.[26][27][28] Although HS shares certain overlapping features with acne vulgaris, such as a tendency to clog skin follicles with skin cell debris, the condition otherwise lacks the hallmark features of acne and is therefore considered a distinct skin disorder.[26]

Tuesday, January 24, 2023

Scanning WordPress with PHPStan

 Scans with PHPStan need a highly customized ruleset to get remotely usable results and even then, they are riddles with false positives, making the output neigh unusable.

Note: this is not necessarily criticism of the PHPStan tooling, but is largely due to the fact that WordPress barely uses type declarations, while PHPStan is primarily geared towards projects using modern code.

An initial scan with the most basic of configurations, yields well over 20.000 issues.

A scan with the above mentioned, highly customized ruleset, aimed at PHP 8 related issues specifically, still yields 580 issues at level 5, another 2.150 potential issues at level 7, though these will likely contain a lot of false positives and yet 380 more issues at level 8 with the same caveat.

A Trac ticket was opened a while back to address a list of issues based on an unknown configuration, but specifically aimed at passed parameter type mismatches (level 5). There is a draft PR available to fix these issues.

An initial assessment of this PR, however, shows that the majority of fixes proposed would hide issues by typecasting variables to the expected type, not actually fix them by doing proper type checking. This can lead to unexpected behaviour in the application if these changes are not accompanied by strict unit tests (and they are not). This will also likely result in much harder to debug errors further down the line.

At this time, it has not been verified whether the fixes proposed are even warranted or that the issues identified should be considered false positives.

Scans run with PHPStan 0.12.52.

Testing

Due to the nature of the problematic changes in PHP 8.0, static analysis can only go so far. Manually reviewing and testing software is painstaking work and humans are very prone to overlook things when there is a lot to be looking out for.

Manually testing performed by end-users tends to be relatively useless, as this will generally only result in “happy paths” being tested. Comprehensive exploratory and regression testing is needed to achieve more reliable results. And even if problems are found, it requires extensive debugging to figure out the cause of the problem – WordPress ? Plugin Theme ? – and whether it is related to PHP compatibility.

More than anything it is important to have automated tests of good quality and to run these on PHP 8, as this will give the best indication of PHP 8.0 problems to expect.

Running automated tests on PHP 8

Getting an automated test suite to run on PHP 8 takes us down the next rabbit hole as the de facto tool for unit testing in the PHP world, PHPUnit, generally does a major release every year and with each major drops support for older PHP versions and introduces breaking changes. The first PHPUnit version which is officially compatible with PHP 8.0 is PHPUnit 9.3, released August 2020.

As WordPress still supports PHP 5.6 as a minimum, to run tests on PHP 8.0, any WordPress related test suite will have to be compatible with PHPUnit 5 up to PHPUnit 9.

While tooling is being built to help with that (look out for a blogpost about this over the next week!), it still takes time and effort to implement these tools and make a test suite compatible. Time which is taken away from the time available to actually fix PHP 8 related problems.

Getting the tests to run on PHP 8 for WP Core

The tests for WP Core are run against PHP 8 and are currently passing. The tests are being run on a composer installed version of PHPUnit 7.5, even though PHPUnit 9.3 is the earliest PHPUnit version officially compatible with PHP 8.0.

This last point has been overcome by copying a select number of files/classes from PHPUnit 9.3 to the WP test suite, excluding the PHPUnit native classes from the Composer autoload generation, in favour of using the copies from PHPUnit 9.3 in the WP test suite. While this works for now, this is a hacky solution and may not be sustainable in the future, aside from the maintenance it may currently require.

Note: while all other WordPress Core CI builds use the Phar version of PHPUnit, this is not possible when running PHPUnit 7.5 on PHP 8.0 as PHPUnit 7 is no longer maintained and the Phar contains incompatible dependencies of PHPUnit. Using a Composer based install of PHPUnit overcomes this as it will pull in the latest compatible versions of the dependencies, though –ignore-platform-reqs is needed.

As for the quality of the tests, this was relatively low to begin with, with loose type checking being used in the majority of cases.

A Trac ticket to address this was already opened in 2016. With an eye on the stricter type adherence in PHP 8.0, this ticket has been revived and a lot of work has been done to mitigate this.

At the time of writing, there are nearly 800 instances (676 assertEquals() + 96 assertNotEquals()) still using loose type checking – down from over 8000 instances.

In part the remaining loose type assertions are legitimate when objects are being compared, in part these still need to be addressed, but would currently result in test failures. These last ones highlight shortcomings either in the tests, but more often in the code being tested.

changes in PHP 8

 

Other breaking changes.

There are many other (breaking) changes in PHP 8, including significant changes to the return types of select, but often-used, functions, resources being turned into Value Objects and more. Examples for GD, OpenSSL, Sockets, XML, Zlib, substr() et al.

Above we’ve tried to highlight the ones that are likely to directly impact WordPress (and many other legacy systems) in a significant way. We’ve based this overview on the excellent guide “What’s new in PHP 8” on stitcher.io and the PHP 8 upgrade guide. For more information we refer you to those sources.

Part 2: Compatibility challenges

To make an existing codebase compatible with a new version of PHP, there are a couple of different strategies that can be deployed for discovery:

  • Static analysis tools like PHPCompatibility to detect syntactic issues.
  • Automated testing to detect runtime issues.
  • Manual testing to detect runtime issues.

Depending on the coverage of your test suite and the proportion of runtime and syntactic changes, these strategies serve as a good basis for fixing the compatibility of a codebase with a new version of PHP. However, in the case of WordPress and PHP 8, there are quite a few extra challenges which makes it hard to rely on these strategies for fixing compatibility and declaring WordPress compatible with PHP 8. Below we’ll report on which strategies have been deployed for WordPress and what the results were.

Static analysis tools

Due to the nature of some of the changes in PHP 8.0, the issues which can be found using static analysis are limited. And in those cases where static analysis tries to go beyond their traditional capabilities and tries to trace the runtime type and value of variables and constants, the results of such scans will be very prone to false positives.

Aside from that, PHPCompatibility is the only static analysis tool dedicated to finding issues related to PHP cross-version compatibility.

Other static analysis tools will report on a far larger scope of issues. Wading through the results to find the issues which are related to PHP cross-version compatibility and actually correct, is very time-consuming and requires in-depth knowledge of the tooling to configure them for the least amount of noise.

At the same time these tools are in constant flux, trying to keep up with the changes in PHP and updating the available scans, so independently of what has been and can be found at this time, chances are that these tools will find still more issues in the (near) future.

Scanning WordPress with PHPCompatibility

Issues reported early on in the WP 5.6 dev cycle and fixed since based on PHPCompatibility scans:

Another PHP 8 issue detected by PHPCompatibility is “__destruct() will no longer be called after die() in __construct()”. This is correctly detected by the scanner, but upon further analysis has been determined not to be problematic in this particular case.

PHPCompatibility has also detected an issue in code used by the Plugin/Theme editor. Analyses of the involved code has determined there is an underlying oversight in the code. WordPress tries to do minimal analysis of the code in the editor, but doesn’t take PHP 5.3+ (namespaced) code into account. This oversight will now just be made more complex to solve while taking related changes in PHP 8.0 into account.

Scans with PHPCompatibility have been run with the develop version. No version has been released yet containing the PHP 8 specific scans.

Issues detected by the scanner in externally maintained dependencies have been reported there.

Scanning WordPress with Exakat

As of the latest public scan, based on WP trunk of October 16th, Exakat reports a total of 149.567 issues.

Exakat dashboard screenshot

The PHP 8 compatibility report contains a total of 93 issues, but is incomplete as a number of analyses relevant for PHP 8 are not (yet) included in the report.

Exakat report

The “worst” offender based on the PHP 8.0 compatibility report, is parameters in method declarations in child classes being named differently from the parameter in the parent class. This is incompatible with the new PHP 8.0 “named parameters in function calls” feature.

This has been reported in issue Trac 51553 and a patch for this has been attached to the ticket, but has not yet been committed.

Other tasks which ought to be executed to prepare for named parameters in function calls have been listed in this ticket as well, including an action list for one of these tasks. No action has been taken on any of these so far.

The 12 “Unsupported Types with Operators” warnings are mostly false positives and this has been reported to Exakat.

More worrisome are the 14.679 issues reported for using the wrong argument type, 14.135 issues for wrong type with call, 15.605 issues reported for wrong number of arguments, 801 wrong type for native PHP function and 25 wrong parameter type issues.

While it is expected that these reports will contain a large number of false positives as WordPress doesn’t use type declarations and the types are therefore extrapolated from the code found and the types indicated in docblocks, these issues should still be examined individually. Even if only just 1% of the found issues is correct, that would still come down to ~450 errors which still need to be dealt with. Quite apart from the huge amount of time needed to weed out the real issues from the false positives. At the time of writing, the author is not aware of any efforts being made to examine these reports and identify and fix these issues.

A few of the analysis reports by Exakat for other issues related to PHP 8, not contained in the PHP 8.0 compatibility report, have been examined. Patches for these have been submitted and committed over the last week. This includes:

  • A fix for a PHP 8.0 fatal error in the WP Revisions module.
  • A fix for a PHP 8.0 warning in the pomo library.

There are a large number of PHP warnings that have been changed to error exceptions in PHP 8.

 

Warnings converted to error exceptions

There are a large number of PHP warnings that have been changed to error exceptions in PHP 8. 

Error level changes unrelated to RFC’s

The following warnings have been converted to errors probably related to deprecations in PHP 7.x versions:

  • Attempting to write to a property of a non-object. Previously this implicitly created an stdClass object for null, false and empty strings.
  • Attempting to append an element to an array for which the PHP_INT_MAX key is already used.
  • Attempting to use an invalid type (array or object) as an array key or string offset.
  • Attempting to write to an array index of a scalar value.
  • Attempting to unpack a non-array/Traversable.

Reclassified engine warnings

Lots of errors that previously only triggered warnings or notices, have been converted to errors. The following were changed:

  • Undefined variable: Warning instead of notice
  • Undefined array index: warning instead of notice
  • Division by zero: DivisionByZeroError exception instead of warning
  • Attempt to increment/decrement property ‘%s’ of non-object: Error exception instead of warning
  • Attempt to modify property ‘%s’ of non-object: Error exception instead of warning
  • Attempt to assign property ‘%s’ of non-object: Error exception instead of warning
  • Creating default object from empty value: Error exception instead of warning
  • Trying to get property ‘%s’ of non-object: warning instead of notice
  • Undefined property: %s::$%s: warning instead of notice
  • Cannot add element to the array as the next element is already occupied: Error exception instead of warning
  • Cannot unset offset in a non-array variable: Error exception instead of warning
  • Cannot use a scalar value as an array: Error exception instead of warning
  • Only arrays and Traversables can be unpacked: TypeError exception instead of warning
  • Invalid argument supplied for foreach(): TypeError exception instead of warning
  • Illegal offset type: TypeError exception instead of warning
  • Illegal offset type in isset or empty: TypeError exception instead of warning
  • Illegal offset type in unset: TypeError exception instead of warning
  • Array to string conversion: warning instead of notice
  • Resource ID#%d used as offset, casting to integer (%d): warning instead of notice
  • String offset cast occurred: warning instead of notice
  • Uninitialized string offset: %d: warning instead of notice
  • Cannot assign an empty string to a string offset: Error exception instead of warning
  • Supplied resource is not a valid stream resource: TypeError exception instead of warning
  • #The @ operator no longer silences fatal errors
    It’s possible that this change might reveal errors that again were hidden before PHP 8. Make sure to set display_errors=Off on your production servers!

Fatal error for incompatible method signatures

Inheritance errors due to incompatible method signatures between two classes will now throw a fatal error instead of a warning.

Default error reporting level

With PHP 8 the default error reporting level is changed to E_ALL instead of everything but E_NOTICE and E_DEPRECATED. This means that many errors will start showing up which were previously silently ignored.

7.x deprecations

During the PHP 7.x release cycle, each version introduced new deprecations, which have now been finalized as feature removals in PHP 8. This also applies to some deprecation which were already put in place in PHP 5.x, but weren’t removed in the PHP 7.0 release.

Most notably, the following, already deprecated features, have been removed in PHP 8:

  • $php_errormsg
  • create_function()
  • mbstring.func_overload
  • parse_str() without second argument
  • each()
  • assert() with string argument
  • $errcontext argument of error handler
  • String search functions with integer needle
  • Defining a free-standing assert() function
  • The real type (alias for float)
  • Magic quotes legacy
  • array_key_exists() with objects
  • Reflection export() methods
  • implode() parameter order mix
  • Unbinding $this from non-static closures
  • restore_include_path() function
  • allow_url_include ini directive