Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=46339
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 9 Jan 2009 15:53:50 +0000 (15:53 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 9 Jan 2009 15:53:50 +0000 (15:53 +0000)
Before the invocation of a fragment, AT_BEGIN and NESTED variables should be copied from the current JspContext to the JspContext of the fragment (*instead* of the JspContext of the calling page or tag file).
Patch provided by kinman@a.o
TCK passes with this patch applied.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@733072 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/jasper/compiler/Generator.java
java/org/apache/jasper/runtime/JspContextWrapper.java

index 8804f5e..495981d 100644 (file)
@@ -2032,9 +2032,6 @@ class Generator {
 
             n.setBeginJavaLine(out.getJavaLine());
 
-            // Copy virtual page scope of tag file to page scope of invoking
-            // page
-            out.printil("((org.apache.jasper.runtime.JspContextWrapper) this.jspContext).syncBeforeInvoke();");
             String varReaderAttr = n.getTextAttribute("varReader");
             String varAttr = n.getTextAttribute("var");
             if (varReaderAttr != null || varAttr != null) {
@@ -2048,6 +2045,11 @@ class Generator {
             out.print(toGetterMethod(n.getTextAttribute("fragment")));
             out.println(" != null) {");
             out.pushIndent();
+            // Copy virtual page scope of tag file to page scope of invoking
+            // page
+            out.printil("((org.apache.jasper.runtime.JspContextWrapper) this.jspContext).syncBeforeInvoke(");
+            out.print(toGetterMethod(n.getTextAttribute("fragment")));
+            out.println(".getJspContext());");
             out.printin(toGetterMethod(n.getTextAttribute("fragment")));
             out.println(".invoke(_jspx_sout);");
             out.popIndent();
index 11a3b21..b4e2f6a 100644 (file)
@@ -336,6 +336,16 @@ public class JspContextWrapper extends PageContext implements VariableResolver {
        }
 
        /**
+     * Synchronize variables before fragment invokation
+     * @param jspContext The JspContext the variable should sync to.  This
+     *        is usually the context of the page where the fragment is. 
+     */
+    public void syncBeforeInvoke(JspContext jspContext) {
+        copyTagToPageScope(VariableInfo.NESTED, (PageContext)jspContext);
+        copyTagToPageScope(VariableInfo.AT_BEGIN, (PageContext)jspContext);
+    }
+
+    /**
         * Synchronize variables at end of tag file
         */
        public void syncEndTagFile() {
@@ -352,6 +362,17 @@ public class JspContextWrapper extends PageContext implements VariableResolver {
         *            variable scope (one of NESTED, AT_BEGIN, or AT_END)
         */
        private void copyTagToPageScope(int scope) {
+        copyTagToPageScope(scope,  invokingJspCtxt);
+    }
+
+       /**
+     * Copies the variables of the given scope from the virtual page scope of
+     * this JSP context wrapper to the page scope of the specified JSP context.
+     *
+     * @param scope variable scope (one of NESTED, AT_BEGIN, or AT_END)
+     * @param jspContext the target context
+     */
+    private void copyTagToPageScope(int scope, PageContext jspContext) {
                Iterator<String> iter = null;
 
                switch (scope) {
@@ -377,9 +398,9 @@ public class JspContextWrapper extends PageContext implements VariableResolver {
                        Object obj = getAttribute(varName);
                        varName = findAlias(varName);
                        if (obj != null) {
-                               invokingJspCtxt.setAttribute(varName, obj);
+                           jspContext.setAttribute(varName, obj);
                        } else {
-                               invokingJspCtxt.removeAttribute(varName, PAGE_SCOPE);
+                           jspContext.removeAttribute(varName, PAGE_SCOPE);
                        }
                }
        }