This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch merge-hibernate6 in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 5c788073bb1e367049eee09c87d14e5179be838f Author: Walter Duque de Estrada <wbdu...@mac.com> AuthorDate: Sun Aug 17 14:50:37 2025 -0500 partial fix HibernateGormStaticApi --- .../orm/hibernate/HibernateGormStaticApi.groovy | 59 +++++++++------------- .../hibernate/HibernateGormStaticApiSpec.groovy | 9 ++-- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy index d229cc78c6..57d8900e99 100644 --- a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy +++ b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy @@ -458,34 +458,7 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { } } - @Override - List<D> findAll(CharSequence query, Collection params, Map args) { - if(query instanceof GString) { - throw new GrailsQueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped."); - } - String queryString = query.toString() - queryString = normalizeMultiLineQueryString(queryString) - - args = new HashMap(args) - - def template = hibernateTemplate - return (List<D>) template.execute { Session session -> - Query q = (Query) session.createQuery(queryString) - template.applySettings(q) - - params.eachWithIndex { val, int i -> - if (val instanceof CharSequence) { - q.setParameter i, val.toString() - } - else { - q.setParameter i, val - } - } - populateQueryArguments(q, args) - createHqlQuery(session, q).list() - } - } @Override D find(D exampleObject, Map args) { @@ -542,25 +515,29 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { } } - @Override - List executeQuery(CharSequence query, Collection params, Map args) { - if(query instanceof GString) { + + + private List<D> numberedParameterQuery(CharSequence query, Map args, params) { + if (query instanceof GString) { throw new GrailsQueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped."); } - def template = hibernateTemplate + def queryString = query.toString() + queryString = normalizeMultiLineQueryString(queryString) args = new HashMap(args) return (List<D>) template.execute { Session session -> - Query q = (Query) session.createQuery(query.toString(),persistentEntity.javaClass) + + + Query q = (Query) session.createQuery(queryString, persistentEntity.javaClass) template.applySettings(q) params.eachWithIndex { val, int i -> + var index = i + 1 if (val instanceof CharSequence) { - q.setParameter i, val.toString() - } - else { - q.setParameter i, val + q.setParameter index, val.toString() + } else { + q.setParameter index, val } } populateQueryArguments(q, args) @@ -568,6 +545,16 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { } } + @Override + List executeQuery(CharSequence query, Collection params, Map args) { + numberedParameterQuery(query, args, params) + } + + @Override + List<D> findAll(CharSequence query, Collection params, Map args) { + numberedParameterQuery(query, args, params) + } + @Override D findWhere(Map queryMap, Map args) { if (!queryMap) return null diff --git a/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy index 9cdd2d85bb..51d5a293a7 100644 --- a/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy +++ b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy @@ -404,12 +404,11 @@ class HibernateGormStaticApiSpec extends HibernateGormDatastoreSpec { new HibernateGormStaticApiEntity(name: "test2").save(flush: true, failOnError: true) when: - def names = HibernateGormStaticApiEntity.executeQuery("select h.name from HibernateGormStaticApiEntity h where h.name like ?", ['test%']) + def entities = HibernateGormStaticApiEntity.executeQuery("from HibernateGormStaticApiEntity h where h.name like ?1", ['test%']) then: - names.size() == 2 - names.contains('test1') - names.contains('test2') + entities.size() == 2 + entities.collect{ it.name}.containsAll(['test1', 'test2']) } void "Test executeQuery with named params"() { @@ -433,7 +432,7 @@ class HibernateGormStaticApiSpec extends HibernateGormDatastoreSpec { new HibernateGormStaticApiEntity(name: "other").save(flush: true, failOnError: true) when: - def instances = HibernateGormStaticApiEntity.findAll("from HibernateGormStaticApiEntity where name = ?", ['test']) + def instances = HibernateGormStaticApiEntity.findAll("from HibernateGormStaticApiEntity where name = ?1", ['test']) then: instances.size() == 2