SLING-9696 - HTL does not correctly cast the "false" string to Boolean

* corrected binary attribute handling so that it does not rely on casting
the attribute value to boolean, but rather comparing it to the empty
string or false
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java b/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
index 2a58176..d3c5b10 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
@@ -40,6 +40,7 @@
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.BooleanConstant;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.Identifier;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.NullLiteral;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
 import org.apache.sling.scripting.sightly.impl.compiler.Patterns;
@@ -187,27 +188,13 @@
         // altogether
         Expression expression = expressionWrapper.transform(interpolation, getAttributeMarkupContext(name), ExpressionContext.ATTRIBUTE);
         String attrContent = symbolGenerator.next("attrContent");
-        String shouldDisplayAttr = symbolGenerator.next("shouldDisplayAttr");
         stream.write(new VariableBinding.Start(attrContent, expression.getRoot()));
-        stream.write(
-                new VariableBinding.Start(
-                        shouldDisplayAttr,
-                        new BinaryOperation(
-                                BinaryOperator.OR,
-                                new Identifier(attrContent),
-                                new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrContent))
-                        )
-                )
-        );
-        stream.write(new Conditional.Start(shouldDisplayAttr, true));
         emitAttributeStart(name);
         invoke.beforeAttributeValue(stream, name, expression.getRoot());
         emitAttributeValueStart(quoteChar);
         stream.write(new OutputVariable(attrContent));
         emitAttributeEnd(quoteChar);
         invoke.afterAttributeValue(stream, name);
-        stream.write(Conditional.END);
-        stream.write(VariableBinding.END);
         stream.write(VariableBinding.END);
     }
 
@@ -234,9 +221,16 @@
                     new VariableBinding.Start(
                             shouldDisplayAttr,
                             new BinaryOperation(
-                                    BinaryOperator.OR,
-                                    new Identifier(attrContent),
-                                    new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrValue))
+                                    BinaryOperator.AND,
+                                    new BinaryOperation(
+                                            BinaryOperator.AND,
+                                            new BinaryOperation(BinaryOperator.NEQ, NullLiteral.INSTANCE, new Identifier(attrContent)),
+                                            new BinaryOperation(BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrContent))
+                                    ),
+                                    new BinaryOperation(BinaryOperator.AND,
+                                            new BinaryOperation(BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrValue)),
+                                            new BinaryOperation(BinaryOperator.NEQ, BooleanConstant.FALSE, new Identifier(attrValue))
+                                    )
                             )
                     )
             );
@@ -246,9 +240,9 @@
                     new VariableBinding.Start(
                             shouldDisplayAttr,
                             new BinaryOperation(
-                                    BinaryOperator.OR,
-                                    new Identifier(attrValue),
-                                    new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrValue))
+                                    BinaryOperator.AND,
+                                    new BinaryOperation(BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrValue)),
+                                    new BinaryOperation(BinaryOperator.NEQ, BooleanConstant.FALSE, new Identifier(attrValue))
                             )
                     )
             );
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java
index 469f590..a0ef200 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AttributePlugin.java
@@ -36,6 +36,7 @@
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.BooleanConstant;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.Identifier;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.NullLiteral;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.PropertyAccess;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
@@ -163,14 +164,21 @@
             stream.write(new VariableBinding.Start(attrValue, node));
             stream.write(new VariableBinding.Start(escapedAttrValue, contentNode));
             stream.write(
-                    new VariableBinding.Start(
-                            shouldDisplayAttribute,
-                            new BinaryOperation(
-                                    BinaryOperator.OR,
-                                    new Identifier(escapedAttrValue),
-                                    new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrValue))
-                            )
-                    )
+                new VariableBinding.Start(
+                    shouldDisplayAttribute,
+                        new BinaryOperation(
+                                BinaryOperator.AND,
+                                new BinaryOperation(
+                                        BinaryOperator.AND,
+                                        new BinaryOperation(BinaryOperator.NEQ, NullLiteral.INSTANCE, new Identifier(escapedAttrValue)),
+                                        new BinaryOperation(BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(escapedAttrValue))
+                                ),
+                                new BinaryOperation(BinaryOperator.AND,
+                                        new BinaryOperation(BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrValue)),
+                                        new BinaryOperation(BinaryOperator.NEQ, BooleanConstant.FALSE, new Identifier(attrValue))
+                                )
+                        )
+                )
             );
             stream.write(new Conditional.Start(shouldDisplayAttribute, true));
         }
@@ -293,9 +301,16 @@
                     new VariableBinding.Start(
                             shouldDisplayAttribute,
                             new BinaryOperation(
-                                    BinaryOperator.OR,
-                                    new Identifier(escapedContent),
-                                    new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrContentVar))
+                                    BinaryOperator.AND,
+                                    new BinaryOperation(
+                                            BinaryOperator.AND,
+                                            new BinaryOperation(BinaryOperator.NEQ, NullLiteral.INSTANCE, new Identifier(escapedContent)),
+                                            new BinaryOperation(BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(escapedContent))
+                                    ),
+                                    new BinaryOperation(BinaryOperator.AND,
+                                            new BinaryOperation(BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrContentVar)),
+                                            new BinaryOperation(BinaryOperator.NEQ, BooleanConstant.FALSE, new Identifier(attrContentVar))
+                                    )
                             )
                     )
             );