cfproperty tag lucee allows non quoted properties

Description

I’m not sure whether this is Lucee specific but Lucee allows the following in a CFC

e.g.

component accessors=true {
property name="viewlet" type="string" default="";
property name="chain" type="array" default=ArrayNew(1);

Note the second property is not wrapped in ““

Attachments

1
  • 19 Sep 2024, 01:56 AM

Activity

Show:

Brad Wood September 19, 2024 at 1:56 AM

Thinking a little further on this-- how we parse the values really boils down to whether we consider a script property to be

  • a first-class construct

  • just a generic-tag-in-script construct

Both have a concept of key="value" pairs, but they follow different parsing rules. First-class constructs (which consists of classes, interfaces, functions, and properties) have annotations, but tags-in-script (such as cfheader() or header xxx; have attributes. The naming may seem arbitrary, but they each have different rules.

  • annotations follow the rules I described above. They are essentially part of the metadata of your class or function or interface and their values can only be literals. Unquoted annotations are just strings.

  • attributes are not baked statically into a function or a class and are evaluated at runtime. Their attribute values can be any valid expression. Unquoted attributes are considered variable expressions.

Ex:

function foo() brad=wood { }

The annotation value wood is a string, not a variable.

var myValue = "text/html" // tag-in-script <cfheader> header name="Content-Type" value=myValue;

The attribute value myValue is a variable, evaluated at runtime.

While there is a <CFProperty> tag in CFML tag-based syntax, the script counterpart is a bit of a snowflake, allowing “shortcut” syntaxes like

property String typedShortcutWithDefault default="myDefaultValue2";

As such, we don’t use a generic tag-in-script rule to match it as a component, but instead have a first-class parser rule, that treats it as a construct having annotations, not attributes since it’s not really a cfproperty “tag” in the script context.

So, back to Lucee-- Lucee allows unquoted values in script property constructs, and it treats them as strings, not variables.

property name=myProperty default=myDefaultValue type=string;

Therefore, it feels like property is NOT being treated like a tag-in-script with attributes, but like a first-class construct with literal annotations.

So, I went back and tested your actual example from the ticket

property name="chain" type="array" default=ArrayNew(1);

and I’ve found that it doesn’t work as you claimed! In my tests using Lucee 5.4.4, the default value on my property is the string "ArrayNew(1)"

image-20240919-015200.png

So I guess that calls into question the entire bug report here slightly smiling face

In related news, I have fixed property default values like

property name="chain" type="array" default="#ArrayNew(1)#";

to work now, so I’ll close this ticket and if there’s still actual incompat with Lucee in regards to unquoted defaults that I’m not seeing, you can create a new ticket with a more specific repro case.

Alex Skinner September 17, 2024 at 11:03 PM

The actual code that we have erroring is the property specifying a default of either structNew() or ArrayNew(1) without the ““

But the docs do specify that it should be a literal

Brad Wood September 17, 2024 at 10:53 PM

Ok, so this really doesn’t have to do with the quotes or lack of quotes per se. In our parser in general, attributes are allowed to be any literal value, and identifier, or an fqn, which could be

  • string

  • array

  • struct

  • boolean

  • number

  • foobar (identifier – string with no quotes)

  • foo.bar.baz (fqn)

So right off, someFunction() is not a literal value so the parser will refuse to even parse that code. Properties don’t really have any “special” parsing outside of the “shortcut” syntax. Attributes/annotations for a property are subject to the same rules as any other tag-in-script. I had never seen code like this before and didn’t realize it was even valid:

property name="foo" default=myExpr;

That poses a significant parsing issue since it’s now no longer clear if myExpr is a variable to be evaluated or an unquoted string? Keep in mind this is also valid CF code

property name="myProperty" type=string;

Note the string attribute value is not intended to be an expressions that’s evaluated, but rather an quoted literal.

So, the second example should, in theory, work. It just lands in some weeds of BoxLang I haven’t quite finalized yet.

property name="foo" default="#myExpr#";

Properties are stored statically in the definition of the class, and they are evaluated when the class is first loaded, which happens in a bit of a vacuum that doesn’t have access to any particular context by which to lookup variables or access information about the request or its scopes. This is why the second option errors because the generated code in the static initializer of the class is looking for a Box context to use for the runtime evaluation, but it can’t find one. I can fix this, but it requires some refactoring of how and where the code lives to initializes the defaut value for properties when the class is created.

Brad Wood September 17, 2024 at 9:55 PM

Please show the stacktraces in your tickets. Just saying “doesn’t like it” really doesn’t help me much slightly smiling face

Alex Skinner September 17, 2024 at 12:59 PM

Additionally it seems that it doesn’t like it if its quoted and has hashes either

property name="viewlet" type="string" default=""; property name="chain" type="array" default="#ArrayNew(1)#";

This also fails to transpire

Fixed
Pinned fields
Click on the next to a field label to start pinning.

Details

Assignee

Reporter

Fix versions

Priority

Sentry

Created September 17, 2024 at 11:43 AM
Updated September 19, 2024 at 2:44 AM
Resolved September 19, 2024 at 2:44 AM

Flag notifications