Fix integer overflow for scene size on 32bit systems (#994)

* Fix integer overflow for scene size on 32bit systems
* Cast to double in sqlite to prevent potential overflow
* Add migration to reset scene sizes and scan logic to repopulate if empty
This commit is contained in:
InfiniteTF 2020-12-22 00:29:53 +01:00 committed by GitHub
parent e883e5fe27
commit e84c92355e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 19 additions and 15 deletions

View File

@ -1,8 +1,8 @@
type StatsResultType { type StatsResultType {
scene_count: Int! scene_count: Int!
scenes_size: Int! scenes_size: Float!
image_count: Int! image_count: Int!
images_size: Int! images_size: Float!
gallery_count: Int! gallery_count: Int!
performer_count: Int! performer_count: Int!
studio_count: Int! studio_count: Int!

View File

@ -133,9 +133,9 @@ func (r *queryResolver) Stats(ctx context.Context) (*models.StatsResultType, err
tagsCount, _ := tagsQB.Count() tagsCount, _ := tagsQB.Count()
return &models.StatsResultType{ return &models.StatsResultType{
SceneCount: scenesCount, SceneCount: scenesCount,
ScenesSize: int(scenesSize), ScenesSize: scenesSize,
ImageCount: imageCount, ImageCount: imageCount,
ImagesSize: int(imageSize), ImagesSize: imageSize,
GalleryCount: galleryCount, GalleryCount: galleryCount,
PerformerCount: performersCount, PerformerCount: performersCount,
StudioCount: studiosCount, StudioCount: studiosCount,

View File

@ -20,7 +20,7 @@ import (
var DB *sqlx.DB var DB *sqlx.DB
var dbPath string var dbPath string
var appSchemaVersion uint = 16 var appSchemaVersion uint = 17
var databaseSchemaVersion uint var databaseSchemaVersion uint
const sqlite3Driver = "sqlite3ex" const sqlite3Driver = "sqlite3ex"

View File

@ -0,0 +1 @@
UPDATE `scenes` SET `size` = NULL;

View File

@ -360,7 +360,7 @@ func (t *ScanTask) scanScene() *models.Scene {
// if the mod time of the file is different than that of the associated // if the mod time of the file is different than that of the associated
// scene, then recalculate the checksum and regenerate the thumbnail // scene, then recalculate the checksum and regenerate the thumbnail
modified := t.isFileModified(fileModTime, scene.FileModTime) modified := t.isFileModified(fileModTime, scene.FileModTime)
if modified { if modified || !scene.Size.Valid {
scene, err = t.rescanScene(scene, fileModTime) scene, err = t.rescanScene(scene, fileModTime)
if err != nil { if err != nil {
logger.Error(err.Error()) logger.Error(err.Error())
@ -534,7 +534,7 @@ func (t *ScanTask) scanScene() *models.Scene {
Height: sql.NullInt64{Int64: int64(videoFile.Height), Valid: true}, Height: sql.NullInt64{Int64: int64(videoFile.Height), Valid: true},
Framerate: sql.NullFloat64{Float64: videoFile.FrameRate, Valid: true}, Framerate: sql.NullFloat64{Float64: videoFile.FrameRate, Valid: true},
Bitrate: sql.NullInt64{Int64: videoFile.Bitrate, Valid: true}, Bitrate: sql.NullInt64{Int64: videoFile.Bitrate, Valid: true},
Size: sql.NullString{String: strconv.Itoa(int(videoFile.Size)), Valid: true}, Size: sql.NullString{String: strconv.FormatInt(videoFile.Size, 10), Valid: true},
FileModTime: models.NullSQLiteTimestamp{ FileModTime: models.NullSQLiteTimestamp{
Timestamp: fileModTime, Timestamp: fileModTime,
Valid: true, Valid: true,
@ -610,7 +610,7 @@ func (t *ScanTask) rescanScene(scene *models.Scene, fileModTime time.Time) (*mod
Height: &sql.NullInt64{Int64: int64(videoFile.Height), Valid: true}, Height: &sql.NullInt64{Int64: int64(videoFile.Height), Valid: true},
Framerate: &sql.NullFloat64{Float64: videoFile.FrameRate, Valid: true}, Framerate: &sql.NullFloat64{Float64: videoFile.FrameRate, Valid: true},
Bitrate: &sql.NullInt64{Int64: videoFile.Bitrate, Valid: true}, Bitrate: &sql.NullInt64{Int64: videoFile.Bitrate, Valid: true},
Size: &sql.NullString{String: strconv.Itoa(int(videoFile.Size)), Valid: true}, Size: &sql.NullString{String: strconv.FormatInt(videoFile.Size, 10), Valid: true},
FileModTime: &models.NullSQLiteTimestamp{ FileModTime: &models.NullSQLiteTimestamp{
Timestamp: fileModTime, Timestamp: fileModTime,
Valid: true, Valid: true,

View File

@ -246,8 +246,8 @@ func (qb *ImageQueryBuilder) Count() (int, error) {
return runCountQuery(buildCountQuery("SELECT images.id FROM images"), nil) return runCountQuery(buildCountQuery("SELECT images.id FROM images"), nil)
} }
func (qb *ImageQueryBuilder) Size() (uint64, error) { func (qb *ImageQueryBuilder) Size() (float64, error) {
return runSumQuery("SELECT SUM(size) as sum FROM images", nil) return runSumQuery("SELECT SUM(cast(size as double)) as sum FROM images", nil)
} }
func (qb *ImageQueryBuilder) CountByStudioID(studioID int) (int, error) { func (qb *ImageQueryBuilder) CountByStudioID(studioID int) (int, error) {

View File

@ -254,8 +254,8 @@ func (qb *SceneQueryBuilder) Count() (int, error) {
return runCountQuery(buildCountQuery("SELECT scenes.id FROM scenes"), nil) return runCountQuery(buildCountQuery("SELECT scenes.id FROM scenes"), nil)
} }
func (qb *SceneQueryBuilder) Size() (uint64, error) { func (qb *SceneQueryBuilder) Size() (float64, error) {
return runSumQuery("SELECT SUM(size) as sum FROM scenes", nil) return runSumQuery("SELECT SUM(cast(size as double)) as sum FROM scenes", nil)
} }
func (qb *SceneQueryBuilder) CountByStudioID(studioID int) (int, error) { func (qb *SceneQueryBuilder) CountByStudioID(studioID int) (int, error) {

View File

@ -332,16 +332,16 @@ func runCountQuery(query string, args []interface{}) (int, error) {
return result.Int, nil return result.Int, nil
} }
func runSumQuery(query string, args []interface{}) (uint64, error) { func runSumQuery(query string, args []interface{}) (float64, error) {
// Perform query and fetch result // Perform query and fetch result
result := struct { result := struct {
Uint uint64 `db:"sum"` Float64 float64 `db:"sum"`
}{0} }{0}
if err := database.DB.Get(&result, query, args...); err != nil && err != sql.ErrNoRows { if err := database.DB.Get(&result, query, args...); err != nil && err != sql.ErrNoRows {
return 0, err return 0, err
} }
return result.Uint, nil return result.Float64, nil
} }
func executeFindQuery(tableName string, body string, args []interface{}, sortAndPagination string, whereClauses []string, havingClauses []string) ([]int, int) { func executeFindQuery(tableName string, body string, args []interface{}, sortAndPagination string, whereClauses []string, havingClauses []string) ([]int, int) {

View File

@ -1,3 +1,5 @@
#### 💥 **Note: After upgrading, all scene file sizes will be 0B until a new [scan](/settings?tab=tasks) is run.
### ✨ New Features ### ✨ New Features
* Add organized flag for scenes, galleries and images. * Add organized flag for scenes, galleries and images.
* Allow configuration of visible navbar items. * Allow configuration of visible navbar items.
@ -14,4 +16,5 @@
* Support configurable number of threads for scanning and generation. * Support configurable number of threads for scanning and generation.
### 🐛 Bug fixes ### 🐛 Bug fixes
* Corrected file sizes on 32bit platforms
* Fixed login redirect to remember the current page. * Fixed login redirect to remember the current page.