Affects Version/s: 7.2.X, 7.3.X, Master
- Set up a new portal
- Activate on local staging on the default Liferay site
- Create a few random pages in staging and delete them (this makes sure that the layoutIds will be different between Live and Staging sites)
- Create 4 widget pages in a hierarchy: PageA ==> PageB ==> PageC ==> PageD
- Create new basic web content "WC1". In the content, create a link to PageD.
- Open PageB and add "WC1" in a web content display portlet
- Publish everything to Live
- Edit WC1, point the link to the Live version of PageD instead of the staging one. Basically, change the link "/web/guest-staging/paged" to "/web/guest/paged".
- Publish everything to Live again
- Shut down the portal
- Execute the following SQL commands on the portal's database. The purpose of this is to make some specific layoutIds equal. This can happen by accident as well, but for the reproduction, it's the only way to make sure:
- Start the portal again, make sure the page structures look the same as before
- Start a new publication, select only PageC and PageD
- Open PageC in Live: http://localhost:8080/web/guest/pagec
Expected: PageC is shown without any errors
Actual: You are redirected to a random page and a StackOverflow error is thrown in the logs
- PageC and PageD will reference each other in their parentLayoutIds. This circular reference causes the permission check to fail.
- The main cause of the issue is that during import, LayoutStagedModelDataHandler.doImportMissingReference(..) updates the layouts data map stored in PortletDataContext with the wrong layoutId. PageD is a missing reference from the web content's point of view, since it does not refer to a page in staging, but the one in live. Later, when the import of PageC is finished (LayoutStagedModelDataHandler.doImportStagedModel(..)), it finds the wrong layout in the PortletDataContext and updates the wrong parentLayoutId in the database.