[MAGNOLIA-8275] NullPointer Exception in HTMLEscapingHttpServletRequest.getCookies() Created: 30/Dec/21  Updated: 20/Jul/22  Resolved: 26/Jan/22

Status: Closed
Project: Magnolia
Component/s: None
Affects Version/s: 6.2.15
Fix Version/s: 6.2.16

Type: Bug Priority: Neutral
Reporter: Jonathan Ayala Assignee: Fernando Cherchi
Resolution: Fixed Votes: 1
Labels: nucleus, quickwin
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File Screenshot 2022-01-21 at 11.32.39.png    
Issue Links:
causality
Template:
Acceptance criteria:
Empty
Task DoD:
[X]* Doc/release notes changes? Comment present?
[X]* Downstream builds green?
[X]* Solution information and context easily available?
[X]* Tests
[X]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[X]* Steps to reproduce, expected, and actual results filled
[X]* Affected version filled
Release notes required:
Yes
Date of First Response:
Epic Link: Nucleus Quality Maintenance
Sprint: Nucleus 2
Story Points: 2
Team: Nucleus

 Description   

Steps to reproduce

  1. Use the following set of instructions in any template script
    script.ftl
    [#if ctx.request.cookies?has_content]
    HELLO
    [/#if]
  1. Force a request without cookies. For example by setting a breakpoint in line info.magnolia.context.HTMLEscapingHttpServletRequest line 74,  and changing value of request.cookies to null
  2. Open and render the template

Expected results

As the method javadoc says, null must be returned by info.magnolia.context.HTMLEscapingHttpServletRequest.getCookies() and the hello message should appears

Actual results

There's a null pointer exception

Development notes

The method is assuming that the value returned by super.getCookies() is never null, which may happen and throw the corresponding exception:

SEVERE [http-nio-8080-exec-4] freemarker.log._JULLoggerFactory$JULLogger.error Error executing FreeMarker template
	FreeMarker template error:
	An error has occurred when reading existing sub-variable "cookies"; see cause exception! The type of the containing value was: extended_hash+string (info.magnolia.context.HTMLEscapingHttpServletRequest wrapped into f.e.b.StringModel)

	----
	FTL stack trace ("~" means nesting-related):
	- Failed at: #if (ctx.request.cookies!?size > 0)  [in template "mtk2/templates/pages/basic.ftl" at line 21, column 1]
	----

	Java stack trace (for programmers):
	----
	freemarker.core._TemplateModelException: [... Exception message was already printed; see it above ...]
		at freemarker.ext.beans.BeanModel.get(BeanModel.java:185)
		at freemarker.core.Dot._eval(Dot.java:43)
		at freemarker.core.Expression.eval(Expression.java:101)
		at freemarker.core.DefaultToExpression._eval(DefaultToExpression.java:96)
		at freemarker.core.Expression.eval(Expression.java:101)
		at freemarker.core.BuiltInsForMultipleTypes$sizeBI._eval(BuiltInsForMultipleTypes.java:504)
		at freemarker.core.Expression.eval(Expression.java:101)
		at freemarker.core.EvalUtil.compare(EvalUtil.java:113)
		at freemarker.core.ComparisonExpression.evalToBoolean(ComparisonExpression.java:78)
		at freemarker.core.ParentheticalExpression.evalToBoolean(ParentheticalExpression.java:35)
		at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:48)
		at freemarker.core.Environment.visit(Environment.java:347)
		at freemarker.core.Environment.visit(Environment.java:353)
		at freemarker.core.Environment.process(Environment.java:326)
		at freemarker.template.Template.process(Template.java:383)
		at info.magnolia.freemarker.FreemarkerHelper.render(FreemarkerHelper.java:170)
		at info.magnolia.rendering.renderer.FreemarkerRenderer.onRender(FreemarkerRenderer.java:99)
		at info.magnolia.rendering.renderer.AbstractRenderer.render(AbstractRenderer.java:166)
		at sun.reflect.GeneratedMethodAccessor1073.invoke(Unknown Source)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.lang.reflect.Method.invoke(Method.java:498)
		at info.magnolia.config.source.DefinitionProviderWrapperWithProxyFallback$DirectDelegator.interceptWithReturnValue(DefinitionProviderWrapperWithProxyFallback.java:151)
		at info.magnolia.rendering.renderer.FreemarkerRenderer$ByteBuddy$MRpcsuzM.render(Unknown Source)
		at info.magnolia.rendering.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:119)
		at info.magnolia.rendering.engine.DefaultRenderingEngine$$EnhancerByCGLIB$$965383de.render(<generated>)
		at info.magnolia.rendering.engine.RenderingFilter.render(RenderingFilter.java:195)
		at info.magnolia.rendering.engine.RenderingFilter.handleTemplateRequest(RenderingFilter.java:140)
		at info.magnolia.rendering.engine.RenderingFilter.doFilter(RenderingFilter.java:94)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.rendering.model.ModelExecutionFilter.doFilter(ModelExecutionFilter.java:109)
		at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:59)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.personalization.filter.VariantResolverFilter.doFilter(VariantResolverFilter.java:131)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.AggregatorFilter.doFilter(AggregatorFilter.java:133)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.security.BaseSecurityFilter.doFilter(BaseSecurityFilter.java:57)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.RepositoryMappingFilter.doFilter(RepositoryMappingFilter.java:121)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:75)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:74)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:75)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.module.cache.executor.Bypass.processCacheRequest(Bypass.java:58)
		at info.magnolia.module.cache.executor.CompositeExecutor.processCacheRequest(CompositeExecutor.java:66)
		at info.magnolia.module.cache.filter.CacheFilter.doFilter(CacheFilter.java:164)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.i18n.I18nContentSupportFilter.doFilter(I18nContentSupportFilter.java:85)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.virtualuri.VirtualUriFilter.doFilter(VirtualUriFilter.java:98)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.RangeSupportFilter.doFilter(RangeSupportFilter.java:78)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.security.BaseSecurityFilter.doFilter(BaseSecurityFilter.java:57)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.multisite.filters.CrossSiteSecurityFilter.doFilter(CrossSiteSecurityFilter.java:104)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cors.AbstractCorsFilter.doFilter(AbstractCorsFilter.java:77)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:79)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.security.SecurityCallbackFilter.doFilter(SecurityCallbackFilter.java:84)
		at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:59)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.security.LogoutFilter.doFilter(LogoutFilter.java:94)
		at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:59)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.module.site.filters.SiteMergeFilter.doFilter(SiteMergeFilter.java:119)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.multisite.filters.MultiSiteFilter.doFilter(MultiSiteFilter.java:120)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.MultiChannelFilter.doFilter(MultiChannelFilter.java:83)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.sitemesh.webapp.MagnoliaSiteMeshFilter.bufferAndPostProcess(MagnoliaSiteMeshFilter.java:95)
		at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
		at org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
		at org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
		at info.magnolia.sitemesh.config.MagnoliaConfigurableSiteMeshFilter.doFilter(MagnoliaConfigurableSiteMeshFilter.java:92)
		at info.magnolia.cms.filters.FilterDecorator.doFilter(FilterDecorator.java:90)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.module.cache.filter.GZipFilter.doFilter(GZipFilter.java:74)
		at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:59)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.security.auth.login.LoginFilter.doFilter(LoginFilter.java:128)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.enterprise.registration.RegistrationFilter.doFilter(RegistrationFilter.java:91)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:74)
		at info.magnolia.cms.security.CsrfTokenFilterBase.doFilter(CsrfTokenFilterBase.java:99)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:75)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:81)
		at info.magnolia.cms.filters.MultipartRequestFilter.doFilter(MultipartRequestFilter.java:151)
		at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:59)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.personalization.preview.filter.PreviewFilter.doFilter(PreviewFilter.java:92)
		at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:59)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.personalization.trait.AbstractTraitDetectorFilter.doFilter(AbstractTraitDetectorFilter.java:80)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.personalization.trait.AbstractTraitDetectorFilter.doFilter(AbstractTraitDetectorFilter.java:80)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.personalization.trait.AbstractTraitDetectorFilter.doFilter(AbstractTraitDetectorFilter.java:80)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.personalization.trait.AbstractTraitDetectorFilter.doFilter(AbstractTraitDetectorFilter.java:80)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.ContentTypeFilter.doFilter(ContentTypeFilter.java:155)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.ContextFilter.doFilter(ContextFilter.java:128)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:79)
		at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:75)
		at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:85)
		at info.magnolia.cms.filters.SafeDestroyMgnlFilterWrapper.doFilter(SafeDestroyMgnlFilterWrapper.java:107)
		at info.magnolia.cms.filters.MgnlFilterDispatcher.doDispatch(MgnlFilterDispatcher.java:67)
		at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:110)
		at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:96)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
		at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
		at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
		at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
		at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
		at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
		at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
		at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
		at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)
		at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
		at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
		at java.lang.Thread.run(Thread.java:745)
	Caused by: java.lang.reflect.InvocationTargetException
		at sun.reflect.GeneratedMethodAccessor1089.invoke(Unknown Source)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.lang.reflect.Method.invoke(Method.java:498)
		at freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:1552)
		at freemarker.ext.beans.BeanModel.invokeThroughDescriptor(BeanModel.java:233)
		at freemarker.ext.beans.BeanModel.get(BeanModel.java:152)
		... 179 more
	Caused by: java.lang.NullPointerException
		at java.util.Arrays.stream(Arrays.java:5004)
		at info.magnolia.context.HTMLEscapingHttpServletRequest.getCookies(HTMLEscapingHttpServletRequest.java:74)
		... 185 more


 Comments   
Comment by Roman Kovařík [ 07/Jan/22 ]

Closing, as 

The super method can return null, see

https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpServletRequest.html#getCookies--

Comment by Alagappan Arjunan [ 07/Jan/22 ]

 

But the Arrays.stream(super.getCookies()) [used in HTMLEscapingHttpServletRequest ]will throw a NPE if the super.getCookies() is null as per Java Array Documentation.

Please reopen and check this issue.

Comment by Roman Kovařík [ 07/Jan/22 ]

Hello arjunan.alagappan,

 

You're right, we've misread the description.

 

Regards.

Roman

Comment by Fernando Cherchi [ 18/Jan/22 ]

Fix of a null pointer exception.

Comment by Fernando Cherchi [ 21/Jan/22 ]

I could manage to reproduce it without tweaking the value in the cookies variable at run time.

My way to reproduce it was:

  • Configure Brave browser, as 'Do Not Track' in privacy settings. (image attached)
  • Launch a 'New private window' of the browser (aka incognito mode)
  • Paste the URL of the page containing the offending script into the address bar.

Expected behavior before the fix:

  • Null pointer exception should happen.

 (I could only reproduce it the first time it lands to the page.)

 

 

Comment by Fernando Cherchi [ 26/Jan/22 ]

A fix for a Null Pointer Exception when cookies are null.

Generated at Mon Feb 12 04:31:13 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.