Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encodeAsHTML is anavailable by default in Grails 3.3.8 projects but other encoders are #13679

Open
Razorfang opened this issue Sep 24, 2024 · 1 comment

Comments

@Razorfang
Copy link

Expected Behavior

As specified in the Grails 3.3.8 documentation here, the HTML codec should come as standard, and thus should provide the encodeAsHTML method on all objects. However, I believe that for Grails 3.3.8, it is not the case.

I have created the following tests to verify that codecs work by default due to issues I am having in a project I am trying to port from Grails 2.5.6 to Grails 6.2.0. I am doing this porting in intermediate steps, so I am currently trying to port from Grails 2.5.6 to Grails 3.3.8.

I tried to create a blank project to see if the issue I was having with codecs was isolated to me, but I don't think it is. I feel that I am missing something.

Here are the tests, located in the file src/test/groovy/EncoderTestsSpec.groovy:

import spock.lang.Specification

class EncoderTestsSpec extends Specification {

  def 'Ensure we can call encodeAsHTML successfully in our application'() {

    expect:
    '"<script>"'.encodeAsHTML() == '&quot;&lt;script&gt;&quot;'
  }

  def 'Ensure we can call encodeAsBase64 successfully in our application'() {

    expect:
    '"<script>"'.encodeAsBase64() == 'IjxzY3JpcHQ+Ig=='
  }

  def 'Ensure we can call encodeAsMD5 successfully in our application'() {

    expect:
    '"<script>"'.encodeAsMD5() == '94936c5d221680f28f4128694dfd5c3f'
  }
}

I expect all of these tests to pass.

Actual Behaviour

The base64 and md5 tests pass but the html test does not. I get the following error in my test output:

Condition failed with Exception:

'"<script>"'.encodeAsHTML() == '&quot;&lt;script&gt;&quot;'
             |
             groovy.lang.MissingMethodException: No signature of method: java.lang.String.encodeAsHTML() is applicable for argument types: () values: []
             Possible solutions: encodeAsHex(), encodeAsSHA1(), encodeAsMD5(), encodeAsSHA256()

	at EncoderTestsSpec.Ensure we can call encodeAsHTML successfully in our application(ExampleSpec.groovy:8)
Caused by: groovy.lang.MissingMethodException: No signature of method: java.lang.String.encodeAsHTML() is applicable for argument types: () values: []
Possible solutions: encodeAsHex(), encodeAsSHA1(), encodeAsMD5(), encodeAsSHA256()
	... 1 more

Steps To Reproduce

  • Using Grails 3.3.8, create a new app with the command grails create-app -features hibernate5 -profile web virtualhome
  • Add in the following tests in the file src/test/groovy/ExampleSpec.groovy.
  • Run the command grails test-app -unit to execute the tests

import spock.lang.Specification

class EncoderTestsSpec extends Specification {

  def 'Ensure we can call encodeAsHTML successfully in our application'() {

    expect:
    '"<script>"'.encodeAsHTML() == '&quot;&lt;script&gt;&quot;'
  }

  def 'Ensure we can call encodeAsBase64 successfully in our application'() {

    expect:
    '"<script>"'.encodeAsBase64() == 'IjxzY3JpcHQ+Ig=='
  }

  def 'Ensure we can call encodeAsMD5 successfully in our application'() {

    expect:
    '"<script>"'.encodeAsMD5() == '94936c5d221680f28f4128694dfd5c3f'
  }
}

Environment Information

I am using a Macbook air running MacOS Sonoma 14.6.1. I am running grails 3.3.8. The following commands are what I copy-paste to set up my environment:

jenv global 1.8.0.412
export JAVA_HOME=$(jenv javahome)
sdk install grails 3.3.8
sdk use grails 3.3.8
sdk install groovy 2.4.15
sdk use groovy 2.4.15
export GRAILS_HOME=$(dirname $(dirname $(which grails)))
export GROOVY_HOME=$(dirname $(dirname $(which groovy)))
export PATH=$JAVA_HOME/bin:$GRAILS_HOME/bin:$GROOVY_HOME/bin:$PATH

My application.yml file is unchanged from the default:

---
grails:
    profile: web
    codegen:
        defaultPackage: virtualhome
    gorm:
        reactor:
            # Whether to translate GORM events into Reactor events
            # Disabled by default for performance reasons
            events: false
info:
    app:
        name: '@info.app.name@'
        version: '@info.app.version@'
        grailsVersion: '@info.app.grailsVersion@'
spring:
    main:
        banner-mode: "off"
    groovy:
        template:
            check-template-location: false

# Spring Actuator Endpoints are Disabled by Default
endpoints:
    enabled: false
    jmx:
        enabled: true

---
grails:
    mime:
        disable:
            accept:
                header:
                    userAgents:
                        - Gecko
                        - WebKit
                        - Presto
                        - Trident
        types:
            all: '*/*'
            atom: application/atom+xml
            css: text/css
            csv: text/csv
            form: application/x-www-form-urlencoded
            html:
              - text/html
              - application/xhtml+xml
            js: text/javascript
            json:
              - application/json
              - text/json
            multipartForm: multipart/form-data
            pdf: application/pdf
            rss: application/rss+xml
            text: text/plain
            hal:
              - application/hal+json
              - application/hal+xml
            xml:
              - text/xml
              - application/xml
    urlmapping:
        cache:
            maxsize: 1000
    controllers:
        defaultScope: singleton
    converters:
        encoding: UTF-8
    views:
        default:
            codec: html
        gsp:
            encoding: UTF-8
            htmlcodec: xml
            codecs:
                expression: html
                scriptlets: html
                taglib: none
                staticparts: none
endpoints:
    jmx:
        unique-names: true

---
hibernate:
    cache:
        queries: false
        use_second_level_cache: false
        use_query_cache: false
dataSource:
    pooled: true
    jmxExport: true
    driverClassName: org.h2.Driver
    username: sa
    password: ''

environments:
    development:
        dataSource:
            dbCreate: create-drop
            url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    test:
        dataSource:
            dbCreate: update
            url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    production:
        dataSource:
            dbCreate: none
            url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
            properties:
                jmxEnabled: true
                initialSize: 5
                maxActive: 50
                minIdle: 5
                maxIdle: 25
                maxWait: 10000
                maxAge: 600000
                timeBetweenEvictionRunsMillis: 5000
                minEvictableIdleTimeMillis: 60000
                validationQuery: SELECT 1
                validationQueryTimeout: 3
                validationInterval: 15000
                testOnBorrow: true
                testWhileIdle: true
                testOnReturn: false
                jdbcInterceptors: ConnectionState
                defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED

My build.gradle file is also completely unchanged:

buildscript {
    repositories {
        mavenLocal()
        maven { url "https://repo.grails.org/grails/core" }
    }
    dependencies {
        classpath "org.grails:grails-gradle-plugin:$grailsVersion"
        classpath "org.grails.plugins:hibernate5:${gormVersion-".RELEASE"}"
        classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.14.8"
    }
}

version "0.1"
group "virtualhome"

apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"war"
apply plugin:"org.grails.grails-web"
apply plugin:"asset-pipeline"
apply plugin:"org.grails.grails-gsp"

repositories {
    mavenLocal()
    maven { url "https://repo.grails.org/grails/core" }
}

dependencies {
    compile "org.springframework.boot:spring-boot-starter-logging"
    compile "org.springframework.boot:spring-boot-autoconfigure"
    compile "org.grails:grails-core"
    compile "org.springframework.boot:spring-boot-starter-actuator"
    compile "org.springframework.boot:spring-boot-starter-tomcat"
    compile "org.grails:grails-web-boot"
    compile "org.grails:grails-logging"
    compile "org.grails:grails-plugin-rest"
    compile "org.grails:grails-plugin-databinding"
    compile "org.grails:grails-plugin-i18n"
    compile "org.grails:grails-plugin-services"
    compile "org.grails:grails-plugin-url-mappings"
    compile "org.grails:grails-plugin-interceptors"
    compile "org.grails.plugins:cache"
    compile "org.grails.plugins:async"
    compile "org.grails.plugins:scaffolding"
    compile "org.grails.plugins:hibernate5"
    compile "org.hibernate:hibernate-core:5.1.5.Final"
    compile "org.grails.plugins:gsp"
    console "org.grails:grails-console"
    profile "org.grails.profiles:web"
    runtime "org.glassfish.web:el-impl:2.1.2-b03"
    runtime "com.h2database:h2"
    runtime "org.apache.tomcat:tomcat-jdbc"
    runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.14.8"
    testCompile "org.grails:grails-gorm-testing-support"
    testCompile "org.grails:grails-web-testing-support"
}

bootRun {
    jvmArgs('-Dspring.output.ansi.enabled=always')
    addResources = true
    String springProfilesActive = 'spring.profiles.active'
    systemProperty springProfilesActive, System.getProperty(springProfilesActive)
}


assets {
    minifyJs = true
    minifyCss = true
}

Example Application

No response

Version

3.3.8

@Razorfang Razorfang changed the title encodeAsHTML is unavaibale by default in Grails 3.3.8 projects but other encoders are encodeAsHTML is anavailable by default in Grails 3.3.8 projects but other encoders are Sep 24, 2024
@Razorfang
Copy link
Author

Do later versions of Grails have this same issue? Can I fix this by skipping version 3 and upgrading from 2.5.6 to version 4.x or later?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant