这是我的琐碎计划:
public class Entity
{
public virtual long Id { get; set; }
public virtual string Payload { get; set; }
}
class Program
{
static void Main( string[] args )
{
var config = new Configuration().Configure();
var sessionFactory = config.BuildSessionFactory();
using ( var session = sessionFactory.OpenSession() )
{
var entity = new Entity { Payload = "'))" };
session.Save( entity );
}
}
}
只要为Payload属性分配任何无辜的字符串,例如'Hi there',一切都按预期工作。然而,这个特殊的魔术字符串'))使NHibernate抛出异常:'索引超出范围。当它试图保存实体时,必须是非负的并且小于集合的大小。
我想知道为什么NHibernate关心参数内容。它真的不应该。
或者这个样本可能有些问题?
NHibernate版本是2.1
SQL脚本:
create table tblEntity
(
EntityId BIGINT NOT NULL IDENTITY PRIMARY KEY
,Payload VARCHAR(10) NOT NULL
)
映射:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="MyNamespace.Entity, MyAssembly"
table="tblEntity">
<id name="Id" column="EntityId" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="Payload"/>
</class>
</hibernate-mapping>
NHibernate设置:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string_name">Main</property>
<property name="connection.isolation">ReadCommitted</property>
<property name="default_schema">dbo</property>
<property name="format_sql">true</property>
<property name="query.substitutions">true=1;false=0</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
<mapping assembly="MyAssembly"/>
</session-factory>
</hibernate-configuration>
没有什么特别的,你可以看到,没有太多的错误空间。
System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
System.ThrowHelper.ThrowArgumentOutOfRangeException()
System.Collections.Generic.List`1.get_Item(Int32 index)
NHibernate.AdoNet.Util.BasicFormatter.FormatProcess.CloseParen()
NHibernate.AdoNet.Util.BasicFormatter.FormatProcess.Perform()
NHibernate.AdoNet.Util.BasicFormatter.Format(String source)
NHibernate.AdoNet.Util.SqlStatementLogger.LogCommand(String message, IDbCommand command, FormatStyle style)
NHibernate.AdoNet.Util.SqlStatementLogger.LogCommand(IDbCommand command, FormatStyle style)
NHibernate.AdoNet.AbstractBatcher.LogCommand(IDbCommand command)
NHibernate.AdoNet.AbstractBatcher.Prepare(IDbCommand cmd)
NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
NHibernate.Id.IdentityGenerator.InsertSelectDelegate.ExecuteAndExtract(IDbCommand insert, ISessionImplementor session)
NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session)
NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session)
NHibernate.Action.EntityIdentityInsertAction.Execute()
NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
NHibernate.Impl.SessionImpl.Save(Object obj)
答案 0 :(得分:3)
我已查看对
所做的更改的src / NHibernate的/ ADONET /的Util / BasicFormatter.cs
NH 2.1中存在导致此行为的问题,这已在2.1.1.GA中修复。
Bugtracker:NH-1992
github上的变更集:Commit
答案 1 :(得分:1)
我相信它可能是NHibernate的一个错误。记录命令时(因为您将show_sql
设置为true)它会写出您的命令,它看起来像这样:
insert into tblEntity (Payload) VALUES(@p0); @p0 = ''(('
然后记录器会尝试对字符串进行标记,并被括号弄糊涂。尝试向NHibernate JIRA提交错误。在此期间,您可以尝试关闭show_sql
答案 2 :(得分:0)
我不熟悉NHibernate,但是你所描述的内容看起来好像是因为无意中导致SQL Injection希望链接的wiki页面可能会有所帮助。