Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-35352

unclassified field org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper result when trying to call setResult on wrong type

      I'm not sure if this can be consider a bug but all the information I found using the exception name refers to classes not supported in the sandbox that should be so this case could be the another case.

      I did not find a way to allow this

      org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified field org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper result
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:367)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onSetProperty(SandboxInterceptor.java:217)
      	at org.kohsuke.groovy.sandbox.impl.Checker$5.call(Checker.java:297)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedSetProperty(Checker.java:294)
      	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.setProperty(SandboxInvoker.java:27)
      	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawSet(PropertyAccessBlock.java:21)
      	at WorkflowScript.run(WorkflowScript:87)
      	at ___cps.transform___(Native Method)
      	at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.set(PropertyishBlock.java:76)
      	at com.cloudbees.groovy.cps.impl.AssignmentBlock$ContinuationImpl.assignAndDone(AssignmentBlock.java:66)
      	at sun.reflect.GeneratedMethodAccessor2070.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
      	at com.cloudbees.groovy.cps.impl.LocalVariableBlock$LocalVariable.get(LocalVariableBlock.java:33)
      	at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
      	at com.cloudbees.groovy.cps.impl.LocalVariableBlock.evalLValue(LocalVariableBlock.java:22)
      	at com.cloudbees.groovy.cps.LValueBlock$BlockImpl.eval(LValueBlock.java:55)
      	at com.cloudbees.groovy.cps.LValueBlock.eval(LValueBlock.java:16)
      	at com.cloudbees.groovy.cps.Next.step(Next.java:58)
      	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
      	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:164)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:277)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.java:77)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:186)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:184)
      	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
      	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
      	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      	at java.lang.Thread.run(Thread.java:745)
      Finished: FAILURE
      

          [JENKINS-35352] unclassified field org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper result when trying to call setResult on wrong type

          Jesse Glick added a comment -

          Works here and here. Reopen if you have steps to reproduce from scratch.

          Jesse Glick added a comment - Works here and here . Reopen if you have steps to reproduce from scratch.

          Andras Kovi added a comment -

          I have a minmal Jenkinsfile that reproduces the error:

          #!/bin/groovy
          node {
              try {
                  error('erroneous test')
              } catch (e) {
                  currentBuild.result = hudson.model.Result.FAILURE
                  step([$class: 'ClaimPublisher'])
              }
          }
          

          If I change to currentBuild.result = 'FAILURE', it works fine.

          Andras Kovi added a comment - I have a minmal Jenkinsfile that reproduces the error: #!/bin/groovy node { try { error( 'erroneous test' ) } catch (e) { currentBuild.result = hudson.model.Result.FAILURE step([$class: 'ClaimPublisher' ]) } } If I change to currentBuild.result = 'FAILURE' , it works fine.

          skovin and jglick: I think there are two "problems":

          1. The line currentBuild.result = hudson.model.Result.FAILURE actually fails, because currently (unfortunately) the result can only be set based on String. See org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper#setResult(...):
                @Whitelisted
                public void setResult(String result) throws AbortException {
                    if(!this.currentBuild) {
                        throw new SecurityException("can only set the result property on the current build");
                    } else {
                        this.build().setResult(Result.fromString(result));
                    }
                }
            
            • => So you could use currentBuild.result = hudson.model.Result.FAILURE.toString(), I guess.
            • => jglick would it be possible to also allow using hudson.model.Result (directly), which would be type/typo-safe? (For backwards compatibility of course the old String based approach needs to be kept, I assume.)
          2. After this change, however, I think the second problem should pop up: namely that hudson.model.Result.FAILURE is not whitelisted either.
            • => jglick Would it be possible to whitelist all static result states from hudson.model.Result, e.g.: staticField hudson.model.Result FAILURE?

          Reinhold Füreder added a comment - skovin and jglick : I think there are two "problems": The line currentBuild.result = hudson.model.Result.FAILURE actually fails, because currently (unfortunately) the result can only be set based on String. See org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper#setResult(...) : @Whitelisted public void setResult( String result) throws AbortException { if (! this .currentBuild) { throw new SecurityException( "can only set the result property on the current build" ); } else { this .build().setResult(Result.fromString(result)); } } => So you could use currentBuild.result = hudson.model.Result.FAILURE.toString() , I guess. => jglick would it be possible to also allow using hudson.model.Result (directly), which would be type/typo-safe? (For backwards compatibility of course the old String based approach needs to be kept, I assume.) After this change, however, I think the second problem should pop up: namely that hudson.model.Result.FAILURE is not whitelisted either. => jglick Would it be possible to whitelist all static result states from hudson.model.Result , e.g.: staticField hudson.model.Result FAILURE ?

          Jesse Glick added a comment -

          Just use

          currentBuild.result = 'FAILURE'
          

          Would it be possible to whitelist all static result states from hudson.model.Result

          I prefer not to have scripts import Jenkins API types if at all possible.

          Jesse Glick added a comment - Just use currentBuild.result = 'FAILURE' Would it be possible to whitelist all static result states from hudson.model.Result I prefer not to have scripts import Jenkins API types if at all possible.

          Based on (a) the comment from jglick and (b) abayer's whitelisting of static fields from hudson.model.Result in the course of JENKINS-40849 I dare to resolve this (rather old) issue with "won't fix" – hope nobody minds...

          Because the following type-/typo-safe code can actually be used without further script approvals:

          currentBuild.result = hudson.model.Result.FAILURE.toString()
          

          Reinhold Füreder added a comment - Based on (a) the comment from jglick and (b) abayer 's whitelisting of static fields from hudson.model.Result in the course of JENKINS-40849 I dare to resolve this (rather old) issue with "won't fix" – hope nobody minds... Because the following type-/typo-safe code can actually be used without further script approvals: currentBuild.result = hudson.model.Result.FAILURE.toString()

          Jesse Glick added a comment -

          No, throwing an unclassified field error is a bug. The call should fail, but it should be reporting the same message that standalone Groovy would in this case, whatever that is.

          Jesse Glick added a comment - No, throwing an unclassified field error is a bug. The call should fail, but it should be reporting the same message that standalone Groovy would in this case, whatever that is.

          Andrew Bayer added a comment -

          So the problem is that it'll actually work in standalone Groovy (or non-sandboxed Pipeline code), because Groovy's meta object protocol magic automatically tries to cast the right-hand side to the type of the parameter for setResult(String). Which obviously in the case of the parameter being a String means it just calls toString().

          So the question is should we do the same in script-security?

          Andrew Bayer added a comment - So the problem is that it'll actually work in standalone Groovy (or non-sandboxed Pipeline code), because Groovy's meta object protocol magic automatically tries to cast the right-hand side to the type of the parameter for setResult(String) . Which obviously in the case of the parameter being a String means it just calls toString() . So the question is should we do the same in script-security ?

            Unassigned Unassigned
            jrivero Jose Luis Rivero
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: