From 867a34db03f0ef8662c8174447b7682db5308856 Mon Sep 17 00:00:00 2001 From: Angel Pons <22937129+Th3Fanbus@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:15:42 +0000 Subject: [PATCH 1/2] fix: do not add zero-length filenames in per-target zips (#45) Rewrite the compound conditional to avoid future confusions. This bug has gone unnoticed for so long because Alpakit-generated zip files do not contain folder entries when iterating with a `zipReader`. However, manually generated zip files, e.g. ContentLib mods, could contain folder entries depending on the zipping program used. The resulting zero-length folder in the per-target zips breaks SMM2 on Windows, but not SMM3. --- storage/storage.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/storage/storage.go b/storage/storage.go index da94729e..55d2c4b6 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -386,11 +386,15 @@ func SeparateModTarget(ctx context.Context, body []byte, modID, name, modVersion zipWriter := zip.NewWriter(buf) for _, file := range zipReader.File { - if !strings.HasPrefix(file.Name, target+"/") && file.Name != target+"/" { + if !strings.HasPrefix(file.Name, target+"/") { + continue + } + trimmedName := strings.TrimPrefix(file.Name, target+"/") + if len(trimmedName) == 0 { continue } - err = copyModFileToArchZip(file, zipWriter, strings.TrimPrefix(file.Name, target+"/")) + err = copyModFileToArchZip(file, zipWriter, trimmedName) if err != nil { log.Err(err).Msg("failed to add file to " + target + " archive") From e284fcb841b2ad8b1c12d16f677102eb09fbe222 Mon Sep 17 00:00:00 2001 From: Angel Pons <22937129+Th3Fanbus@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:34:21 +0000 Subject: [PATCH 2/2] fix: urlencode filename for separate mod targets (#47) * fix: urlencode filename for separate mod targets When a mod's name contains characters that should be urlencoded, any newly-uploaded versions cannot be download because of some errors regarding the URL being invalid. Make sure the returned key is urlencoded for consistency with the rest of the codebase. Signed-off-by: Angel Pons * fix: urlencode version in `RenameFilename` As per Mircea's comment on [#44 (comment)](https://github.com/satisfactorymodding/smr-api/pull/44#issuecomment-1902611988): I've also now noticed that RenameVersion is also not correctly escaping the filename, it's only escaping the mod's name, and not the version, which is what causes mods that use build metadata in the version (+build.1234) to fail, so that one should need a similar fix of encoding the filename. Signed-off-by: Angel Pons --------- Signed-off-by: Angel Pons --- storage/storage.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/storage/storage.go b/storage/storage.go index 55d2c4b6..9c2ec55c 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -276,7 +276,7 @@ func RenameVersion(ctx context.Context, modID string, name string, versionID str return false, "" } - return true, fmt.Sprintf("/mods/%s/%s.smod", modID, EncodeName(cleanName)+"-"+version) + return true, fmt.Sprintf("/mods/%s/%s.smod", modID, EncodeName(cleanName+"-"+version)) } func DeleteMod(ctx context.Context, modID string, name string, versionID string) bool { @@ -404,7 +404,8 @@ func SeparateModTarget(ctx context.Context, body []byte, modID, name, modVersion zipWriter.Close() - key := fmt.Sprintf("/mods/%s/%s.smod", modID, cleanName+"-"+target+"-"+modVersion) + filename := cleanName + "-" + target + "-" + modVersion + key := fmt.Sprintf("/mods/%s/%s.smod", modID, filename) _, err = storage.Put(ctx, key, bytes.NewReader(buf.Bytes())) if err != nil { @@ -415,7 +416,8 @@ func SeparateModTarget(ctx context.Context, body []byte, modID, name, modVersion hash := sha256.New() hash.Write(buf.Bytes()) - return true, key, hex.EncodeToString(hash.Sum(nil)), int64(buf.Len()) + encodedKey := fmt.Sprintf("/mods/%s/%s.smod", modID, EncodeName(filename)) + return true, encodedKey, hex.EncodeToString(hash.Sum(nil)), int64(buf.Len()) } func copyModFileToArchZip(file *zip.File, zipWriter *zip.Writer, newName string) error {