revolution icon indicating copy to clipboard operation
revolution copied to clipboard

readdir() not a valid Directory resource in xpdocachemanager.class.php

Open jenswittmann opened this issue 2 years ago • 6 comments

Bug report

Summary

I have a resource with a snippet [[apiPhotoResize]] in it. The resource is uncached, the snippet cached. Its used to resize images on a webpage, to load faster as using pThumb directly inside the document. This resource getting requested 180 times/second on a pageload.

I get some PHP errors:

PHP Fatal error:  Uncaught TypeError: readdir(): supplied resource is not a valid Directory resource in core/xpdo/cache/xpdocachemanager.class.php:504
Stack trace:
#0 core/xpdo/cache/xpdocachemanager.class.php(504): readdir(Resource id #182)
#1 core/xpdo/cache/xpdocachemanager.class.php(1021): xPDOCacheManager->deleteTree('/www/htdocs/w01...', Array)
#2 core/xpdo/cache/xpdocachemanager.class.php(721): xPDOFileCache->delete('modSnippet', Array)
#3 core/xpdo/xpdo.class.php(2360): xPDOCacheManager->delete('modSnippet', Array)
#4 core/xpdo/om/xpdoobject.class.php(1498): xPDO->toCache(Object(xPDOQuery_mysql), Object(modSnippet_mysql), 0, Array)
#5 core/model/modx/modaccessibleobject.class.php(178): xPDOObject->save(NULL)
#6 core/model/modx/modelement.class.php(180): modAccessibleObject->save(NULL)
#7 core/model/modx/modsnippet.class.php(39): modElement->save(NULL)
#8 core/model/modx/modelement.class.php(449): modSnippet->save()
#9 core/model/modx/modelement.class.php(305): modElement->getContent(Array)
#10 core/model/modx/modscript.class.php(65): modElement->process(NULL, NULL)
#11 core/model/modx/modparser.class.php(537): modScript->process(NULL)
#12 core/components/pdotools/model/pdotools/pdoparser.class.php(273): modParser->processTag(Array, false)
#13 core/model/modx/modparser.class.php(251): pdoParser->processTag(Array, false)
#14 core/components/pdotools/model/pdotools/pdoparser.class.php(64): modParser->processElementTags('', '[[apiPhotoResiz...', false, false, '[[', ']]', Array, 0)
#15 core/model/modx/modresource.class.php(520): pdoParser->processElementTags('', '[[apiPhotoResiz...', false, false, '[[', ']]', Array, 0)
#16 core/model/modx/modresponse.class.php(166): modResource->process()
#17 core/model/modx/modrequest.class.php(138): modResponse->outputContent(Array)
#18 core/model/modx/modrequest.class.php(122): modRequest->prepareResponse()
#19 core/model/modx/modx.class.php(1461): modRequest->handleRequest()
#20 site/index.php(54): modX->handleRequest()
#21 {main}
  thrown in core/xpdo/cache/xpdocachemanager.class.php on line 504

I changed this:

https://github.com/modxcms/revolution/blob/6f598964812fa94a1e5885ac8a09e884235a3a17/core/xpdo/cache/xpdocachemanager.class.php#L501

Into this:

if (!is_resource($handle)) {
    continue;
}
while (false !== ($file= @readdir($handle))) {

Environment

MODX 2.8.5 Apache PHP Version 8.1.16

jenswittmann avatar Aug 11 '23 07:08 jenswittmann

Ping @opengeek

rthrash avatar Oct 04 '23 16:10 rthrash

@rthrash — this could be submitted as a PR to the xPDO repository.

opengeek avatar Oct 04 '23 17:10 opengeek

hej @rthrash and @opengeek, today i get this bug on another site so i created a PR https://github.com/modxcms/xpdo/pull/255 for this.

When the error came up on visiting a resource, most user reload the page and get the result. So they don't really notice the error. But if a resource makes an ajax call to another resource (i.e. JSON output) and this produces a Error 500, the bug is more noticeable, because the page is broken.

Hopefully this get fixed in a near version of MODX 2.8.x. I don't this this error on MODX 3 for now.

jenswittmann avatar Jan 16 '24 19:01 jenswittmann

Thanks for the patch @jenswittmann . We're getting this error happening regularly but randomly on a 3.1.0-dev project, itself an upgrade from 2.8.4-pl.

I am still unclear why the problem is happening but the patch works around it and stops the fatal errors 👍

Examples of the errors we're getting:

Fatal error:  Uncaught TypeError: readdir(): supplied resource is not a valid Directory resource in /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php:485
Stack trace:
#0 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php(485): readdir(Resource id #27)
#1 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOFileCache.php(92): xPDO\Cache\xPDOCacheManager->deleteTree('/var/www/html/h...', Array)
#2 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php(703): xPDO\Cache\xPDOFileCache->delete('MODX\\Revolution...', Array)
#3 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/xPDO.php(2387): xPDO\Cache\xPDOCacheManager->delete('MODX\\Revolution...', Array)
#4 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Om/xPDOObject.php(1493): xPDO\xPDO->toCache(Object(xPDO\Om\mysql\xPDOQuery), Object(MODX\Revolution\mysql\modDeprecatedCall), 0, Array)
#5 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Om/xPDOObject.php(1590): xPDO\Om\xPDOObject->save()
#6 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Om/xPDOObject.php(1541): xPDO\Om\xPDOObject->_saveRelatedObject(Object(MODX\Revolution\mysql\modDeprecatedCall), Array)
#7 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Om/xPDOObject.php(1348): xPDO\Om\xPDOObject->_saveRelatedObjects()
#8 /var/www/html/htdocs/core/src/Revolution/modX.php(2445): xPDO\Om\xPDOObject->save()
#9 [internal function]: MODX\Revolution\modX->MODX\Revolution\{closure}()
#10 {main}
  thrown in /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php on line 485
PHP Fatal error:  Uncaught TypeError: readdir(): supplied resource is not a valid Directory resource in /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php:485
Stack trace:
#0 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php(485): readdir(Resource id #391)
#1 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOFileCache.php(92): xPDO\Cache\xPDOCacheManager->deleteTree('/var/www/html/h...', Array)
#2 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php(703): xPDO\Cache\xPDOFileCache->delete('MODX\\Revolution...', Array)
#3 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/xPDO.php(2387): xPDO\Cache\xPDOCacheManager->delete('MODX\\Revolution...', Array)
#4 /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Om/xPDOObject.php(1493): xPDO\xPDO->toCache(Object(xPDO\Om\mysql\xPDOQuery), Object(MODX\Revolution\mysql\modDocument), 0, Array)
#5 /var/www/html/htdocs/core/src/Revolution/modAccessibleObject.php(215): xPDO\Om\xPDOObject->save(NULL)
#6 /var/www/html/htdocs/core/src/Revolution/modResource.php(707): MODX\Revolution\modAccessibleObject->save(NULL)
#7 /var/www/html/htdocs/core/components/npg/ContentBlocksFastRebuildProcessor.php(221): MODX\Revolution\modResource->save()
#8 /var/www/html/htdocs/core/components/npg/ContentBlocksFastRebuildProcessor.php(148): ContentBlocksFastRebuildProcessor->parse(Object(MODX\Revolution\mysql\modDocument), Array)
#9 /var/www/html/htdocs/core/src/Revolution/Processors/Processor.php(189): ContentBlocksFastRebuildProcessor->process()
#10 /var/www/html/htdocs/core/components/npg/ContentBlocksFastRebuildProcessor.php(240): MODX\Revolution\Processors\Processor->run()
#11 {main}
  thrown in /var/www/html/htdocs/core/vendor/xpdo/xpdo/src/xPDO/Cache/xPDOCacheManager.php on line 485

pbowyer avatar Jan 25 '24 11:01 pbowyer

This has been applied to the 2.x, 3.0.x, and 3.x branches of xPDO.

opengeek avatar Jan 25 '24 15:01 opengeek

Thanks @opengeek !

pbowyer avatar Jan 25 '24 15:01 pbowyer