Problem request access

Hello All,

After migrating our server lucee on the latest version (5.3.1.102) we have a piece of code that no longer works.

It is at the bottom of an object and the error is bizard

Here is the error:

image

And the code is :

<cffunction name=“initFromQuery” access=“public” returntype=“boolean” output=“false”>
    <cfargument name=“queryRowData” type=“any” default=“false”>
    <cfargument name=“suffix” type=“string” default="">

    <cfscript>
        var formattedSuffix = “”;

        if (Len(arguments.suffix))
            formattedSuffix = “_” & arguments.suffix;

        if (false || !IsDefined(“queryRowData.CLGR_ID_GROU#formattedSuffix#”) || !IsDefined(“queryRowData.CLGR_ID_CLIE#formattedSuffix#”) || !IsDefined(“queryRowData.CLGR_DEFAULT#formattedSuffix#”))
            return false;

        if (IsDefined(“request.objects.adminclient.ClieGrou”) && StructKeyExists(request.objects.adminclient.ClieGrou, queryRowData[“CLGR_ID_GROU#formattedSuffix#”] & “,” & queryRowData[“CLGR_ID_CLIE#formattedSuffix#”]) && IsInstanceOf(request.objects.adminclient.ClieGrou[queryRowData[“CLGR_ID_GROU#formattedSuffix#”] & “,” & queryRowData[“CLGR_ID_CLIE#formattedSuffix#”]], GetMetaData(this).name)) {
            var cachedObject = request.objects.adminclient.ClieGrou[queryRowData[“CLGR_ID_GROU#formattedSuffix#”] & “,” & queryRowData[“CLGR_ID_CLIE#formattedSuffix#”]];
            StructAppend(this, cachedObject, true);
            return true;
        }

        this.IdGrou = queryRowData[“CLGR_ID_GROU” & formattedSuffix];
        this.IdClie = queryRowData[“CLGR_ID_CLIE” & formattedSuffix];
        this.Default = queryRowData[“CLGR_DEFAULT” & formattedSuffix];

        request.objects.adminclient.ClieGrou[queryRowData[“CLGR_ID_GROU#formattedSuffix#”] & “,” & queryRowData[“CLGR_ID_CLIE#formattedSuffix#”]] = Duplicate(this);

        return true;

    </cfscript>

</cffunction>

Obviously with this new version, Lucee can no longer access the data in the scoop REQUEST

Any suggestion ?

For more information, the problem is when we set the request.objects.adminClient.ClieGrou variable to the cachaedObject variable, it looks like the request.objects.adminclient.ClieGrou variable did not exist.

are you sure the nested structure exists?

you’re checking for it a few lines earlier

IsDefined(“request.objects.adminclient.ClieGrou”)

if (IsDefined(“request.objects.adminclient.ClieGrou”) && StructKeyExists(request.objects.adminclient.ClieGrou, queryRowData[“CLGR_ID_GROU#formattedSuffix#”] & “,” & queryRowData[“CLGR_ID_CLIE#formattedSuffix#”]) && IsInstanceOf(request.objects.adminclient.ClieGrou[queryRowData[“CLGR_ID_GROU#formattedSuffix#”] & “,” & queryRowData[“CLGR_ID_CLIE#formattedSuffix#”]], GetMetaData(this).name)) {

Yes, with this code I check the struct no ?

In version 5.2.8.50 it works. I will come back to this version but I have problems with the downgrade, the transition to version 5.3.1.xx to change something with “could not initialize class com.adobe.xmp.impl.xmpmetaparser” on the images.

well, if both the struct exists and the key exists, you return. but those checks are combined,

if either fail, you’ll end up at the line which crashes

We try to figure out what was happening with a try catch like this.

<cffunction name="initFromQuery" access="public" returntype="boolean" output="false">
    <cfargument name="queryRowData" type="any" default="false">
    <cfargument name="suffix" type="string" default="">

    <cfscript>
        try {
            var formattedSuffix = "";

            if (Len(arguments.suffix))
                formattedSuffix = "_" & arguments.suffix;

            if (false || !IsDefined("queryRowData.CLGR_ID_GROU#formattedSuffix#") || !IsDefined("queryRowData.CLGR_ID_CLIE#formattedSuffix#") || !IsDefined("queryRowData.CLGR_DEFAULT#formattedSuffix#"))
                return false;

            if (IsDefined("request.objects.adminclient.ClieGrou") && StructKeyExists(request.objects.adminclient.ClieGrou, queryRowData["CLGR_ID_GROU#formattedSuffix#"] & "," & queryRowData["CLGR_ID_CLIE#formattedSuffix#"]) && IsInstanceOf(request.objects.adminclient.ClieGrou[queryRowData["CLGR_ID_GROU#formattedSuffix#"] & "," & queryRowData["CLGR_ID_CLIE#formattedSuffix#"]], GetMetaData(this).name)) {
                var cachedObject = request.objects.adminclient.ClieGrou[queryRowData["CLGR_ID_GROU#formattedSuffix#"] & "," & queryRowData["CLGR_ID_CLIE#formattedSuffix#"]];
                StructAppend(this, cachedObject, true);
                return true;
            }

            this.IdGrou = queryRowData["CLGR_ID_GROU" & formattedSuffix];
            this.IdClie = queryRowData["CLGR_ID_CLIE" & formattedSuffix];
            this.Default = queryRowData["CLGR_DEFAULT" & formattedSuffix];

            request.objects.adminclient.ClieGrou[queryRowData["CLGR_ID_GROU#formattedSuffix#"] & "," & queryRowData["CLGR_ID_CLIE#formattedSuffix#"]] = Duplicate(this);
        } catch (any e) {
            writedump(IsDefined("request"));
            writedump(request);
            abort;
        }
        return true;

    </cfscript>

</cffunction>

IsDefined(“request”) obviously return true.

But if we try to dump it we are getting the java.lang.NullPointerException error like if Lucee isn’t able to find or acces to request anymore.

This is error appear at different place where we are calling function “initFromQuery” but not everywhere and we are not able to create a code who trigger the error.

This code work well in version 5.2.9.31 but not this we update the server on 5.3.1.102.

can you try serializeJson(request) ?

I replace

writedump(request);

by

writedump(serializeJson(request));

and I still get a java.lang.NullPointerException

ok, so something in your request scope is triggering this.

can you loop over the request scope and dump out each key name, then dump that scope request[key]?

Do you mean in the catch state ?
Or before calling the function ?

can you run this?

<cfloop collection="#request#" item="r">
	<cfdump var=#r#>
	<cfdump var=#request[r]#>
</cfloop>

I dump each request’s key as below (it come from another component, that’s just why some variable has a different name)

<cffunction name="initFromQuery" access="public" returntype="boolean" output="false">
		<cfargument name="queryRowData" type="any" default="false">
		<cfargument name="suffix" type="string" default="">

		<cfscript>
			try {
				var formattedSuffix = "";
				if (Len(arguments.suffix))
				formattedSuffix = "_" & arguments.suffix;
				
				if (false || !IsDefined("queryRowData.VACO_ID#formattedSuffix#") || !IsDefined("queryRowData.VACO_ID_COFO#formattedSuffix#") || !IsDefined("queryRowData.VACO_ID_TILO#formattedSuffix#") || !IsDefined("queryRowData.VACO_MONT_MIN#formattedSuffix#") || !IsDefined("queryRowData.VACO_MONT_MAX#formattedSuffix#") || !IsDefined("queryRowData.VACO_EFFET_NUM#formattedSuffix#") || !IsDefined("queryRowData.VACO_TYPE_EFFET_NUM#formattedSuffix#") || !IsDefined("queryRowData.VACO_ORDER#formattedSuffix#"))
				return false;
				
				if (queryRowData["VACO_ID#formattedSuffix#"] EQ 78) {
					request.each(function(r, value) {
						dump(r);
						dump(request[r]);
					});
					abort;
				}

				if (IsDefined("request.objects.supplyu.ValuCofo") && StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]) && IsInstanceOf(request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]], GetMetaData(this).name)) {
					var cachedObject = request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]];
					StructAppend(this, cachedObject, true);
					return true;
				}
				
				this.Id = queryRowData["VACO_ID" & formattedSuffix];
				this.IdCofo = queryRowData["VACO_ID_COFO" & formattedSuffix];
				this.IdTilo = queryRowData["VACO_ID_TILO" & formattedSuffix];
				this.MontMin = queryRowData["VACO_MONT_MIN" & formattedSuffix];
				this.MontMax = queryRowData["VACO_MONT_MAX" & formattedSuffix];
				this.EffetNum = queryRowData["VACO_EFFET_NUM" & formattedSuffix];
				this.TypeEffetNum = queryRowData["VACO_TYPE_EFFET_NUM" & formattedSuffix];
				this.Order = queryRowData["VACO_ORDER" & formattedSuffix];
				
				request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]] = Duplicate(this);
			} catch (any e) {
				dump(isDefined("i failed"));
				abort;
			}

			return true;

		</cfscript>
	</cffunction>

I checked queryRowData["VACO_ID#formattedSuffix#"] EQ 78 because it make it crash.

I got it by doing a dump in the catch.

} catch (any e) {
   dump(queryRowData["VACO_ID#formattedSuffix#"]);
   abort;
}

And here is the dump :
dumpRequest.html (689.9 KB)

So, dumping out each individual variable under the request doesn’t crash, but dumping the whole request scope throws a NPE?

What I’m trying to help you do is narrow down the problem to create a minimal reproducible test case

It don’t throw a NPE if i do it before the “if” statement like that

if (queryRowData["VACO_ID#formattedSuffix#"] EQ 78) {
	dump(request);
	abort;
}

if (IsDefined("request.objects.supplyu.ValuCofo") && StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]) && IsInstanceOf(request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]], GetMetaData(this).name)) {
	var cachedObject = request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]];
	StructAppend(this, cachedObject, true);
	return true;
}

However if I dump out each individual variable under the request in the catch statement it throw a NPE

} catch (any e) {
	request.each(function(r, value) {
	    dump(r);
	    dump(request[r]);
	});
	abort;
}

It’s kind like before the “if” statement, it’s ok but it throw an error when it’s checking it

if (IsDefined("request.objects.supplyu.ValuCofo") && StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]) && IsInstanceOf(request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]], GetMetaData(this).name)) {

do you know specifically which individual variable NPE’s?

I decomposed the “if” statement and if I dump these individualy like that

<cffunction name="initFromQuery" access="public" returntype="boolean" output="false">
		<cfargument name="queryRowData" type="any" default="false">
		<cfargument name="suffix" type="string" default="">

		<cfscript>
			try {
				var formattedSuffix = "";
				if (Len(arguments.suffix))
				formattedSuffix = "_" & arguments.suffix;
				
				if (false || !IsDefined("queryRowData.VACO_ID#formattedSuffix#") || !IsDefined("queryRowData.VACO_ID_COFO#formattedSuffix#") || !IsDefined("queryRowData.VACO_ID_TILO#formattedSuffix#") || !IsDefined("queryRowData.VACO_MONT_MIN#formattedSuffix#") || !IsDefined("queryRowData.VACO_MONT_MAX#formattedSuffix#") || !IsDefined("queryRowData.VACO_EFFET_NUM#formattedSuffix#") || !IsDefined("queryRowData.VACO_TYPE_EFFET_NUM#formattedSuffix#") || !IsDefined("queryRowData.VACO_ORDER#formattedSuffix#"))
				return false;
				
				if (queryRowData["VACO_ID#formattedSuffix#"] EQ 78) {
					dump(request.objects.supplyu.ValuCofo);
					dump(StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]));
					dump(IsInstanceOf(request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]], GetMetaData(this).name));
				}

				if (IsDefined("request.objects.supplyu.ValuCofo")) {
					dump("2");
					if (StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]))  {
						dump("3");
						if (IsInstanceOf(request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]], GetMetaData(this).name)) {
							dump("4");
							var cachedObject = request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]];
							dump("5");
							StructAppend(this, cachedObject, true);
							dump("6");
						}
					}
				}
				
				this.Id = queryRowData["VACO_ID" & formattedSuffix];
				this.IdCofo = queryRowData["VACO_ID_COFO" & formattedSuffix];
				this.IdTilo = queryRowData["VACO_ID_TILO" & formattedSuffix];
				this.MontMin = queryRowData["VACO_MONT_MIN" & formattedSuffix];
				this.MontMax = queryRowData["VACO_MONT_MAX" & formattedSuffix];
				this.EffetNum = queryRowData["VACO_EFFET_NUM" & formattedSuffix];
				this.TypeEffetNum = queryRowData["VACO_TYPE_EFFET_NUM" & formattedSuffix];
				this.Order = queryRowData["VACO_ORDER" & formattedSuffix];
				
				request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]] = Duplicate(this);
			} catch (any e) {
				dump(e);
				abort;
			}

			return true;

		</cfscript>
	</cffunction>

it’s saying that the struct key doesn’t exist. (and obviously isInstanceOf throw an error)

However if I put these dump in comment

				if (queryRowData["VACO_ID#formattedSuffix#"] EQ 78) {
					//dump(request.objects.supplyu.ValuCofo);
					dump(StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]));
					//dump(IsInstanceOf(request.objects.supplyu.ValuCofo[queryRowData["VACO_ID#formattedSuffix#"]], GetMetaData(this).name));
				}

The structKeyExists return true and it throw an NPE on this line

StructAppend(this, cachedObject, true);

just a hunch, queryRowData is also a BIF (built in function)?

what happens if you change that variable name?

Hi,

Change the variable name doesn’t change anythings.

The strange thing is that if I dump

dump(request.objects.supplyu.ValuCofo);
dump(StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]));
dump(IsInstanceOf(request.objects.supplyu.ValuCofo[queryRow["VACO_ID#formattedSuffix#"]], GetMetaData(this).name));

request.objects.supplyu.ValuCofo is dump out normaly and StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData[“VACO_ID#formattedSuffix#”]) return false (that’s normal the entry isn’t in the dump of request.objects.supplyu.ValuCofo)

However if I dump only

dump(StructKeyExists(request.objects.supplyu.ValuCofo, queryRowData["VACO_ID#formattedSuffix#"]));

It’s return true but I can’t confirm if that’s correct because if I don’t dump out IsInstanceOf, dumping out request.objects.supplyu.ValuCofo throws a NPE.

It’s seem that the order of the dump doesn’t matter.