Fixed a bug with invalid zero value in preload
When using pointers in model structs, there is an edge case. When using preload to eagerly preload a many to many relationship and the main row is not found by a primary key, use of reflect.Indirect in preload.go results in a zero value and the subsequent call to FieldByName panics the program.
This commit is contained in:
		
							parent
							
								
									ba694926d0
								
							
						
					
					
						commit
						e69ffaa9c4
					
				
							
								
								
									
										17
									
								
								preload.go
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								preload.go
									
									
									
									
									
								
							@ -10,8 +10,15 @@ import (
 | 
			
		||||
 | 
			
		||||
func getRealValue(value reflect.Value, columns []string) (results []interface{}) {
 | 
			
		||||
	for _, column := range columns {
 | 
			
		||||
		if reflect.Indirect(value).FieldByName(column).IsValid() {
 | 
			
		||||
			result := reflect.Indirect(value).FieldByName(column).Interface()
 | 
			
		||||
		pointedValue := reflect.Indirect(value)
 | 
			
		||||
		// If v is a nil pointer, Indirect returns a zero Value!
 | 
			
		||||
		// Therefor we need to check for a zero value,
 | 
			
		||||
		// as FieldByName could panic
 | 
			
		||||
		if !pointedValue.IsValid() {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if pointedValue.FieldByName(column).IsValid() {
 | 
			
		||||
			result := pointedValue.FieldByName(column).Interface()
 | 
			
		||||
			if r, ok := result.(driver.Valuer); ok {
 | 
			
		||||
				result, _ = r.Value()
 | 
			
		||||
			}
 | 
			
		||||
@ -290,6 +297,12 @@ func (scope *Scope) handleManyToManyPreload(field *Field, conditions []interface
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// If v is a nil pointer, Indirect returns a zero Value!
 | 
			
		||||
		// Therefor we need to check for a zero value,
 | 
			
		||||
		// as FieldByName could panic
 | 
			
		||||
		if !scope.IndirectValue().IsValid() {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		object := scope.IndirectValue()
 | 
			
		||||
		source := getRealValue(object, associationForeignStructFieldNames)
 | 
			
		||||
		field := object.FieldByName(field.Name)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user