Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package semaphore for openSUSE:Factory checked in at 2026-07-23 23:10:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/semaphore (Old) and /work/SRC/openSUSE:Factory/.semaphore.new.2004 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "semaphore" Thu Jul 23 23:10:57 2026 rev:53 rq:1367311 version:2.18.28 Changes: -------- --- /work/SRC/openSUSE:Factory/semaphore/semaphore.changes 2026-07-14 13:52:07.795517240 +0200 +++ /work/SRC/openSUSE:Factory/.semaphore.new.2004/semaphore.changes 2026-07-23 23:14:18.368627877 +0200 @@ -1,0 +2,10 @@ +Thu Jul 23 06:03:14 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 2.18.28: + * Bugfixes + - Validate schedule cron format using backend endpoint instead + of JS library +- Update to version 2.18.27: + * fix(templates): validate app + +------------------------------------------------------------------- Old: ---- semaphore-2.18.26.obscpio web-2.18.26.tar.gz New: ---- semaphore-2.18.28.obscpio web-2.18.28.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ semaphore.spec ++++++ --- /var/tmp/diff_new_pack.0XE2VV/_old 2026-07-23 23:14:22.864785988 +0200 +++ /var/tmp/diff_new_pack.0XE2VV/_new 2026-07-23 23:14:22.864785988 +0200 @@ -17,7 +17,7 @@ Name: semaphore -Version: 2.18.26 +Version: 2.18.28 Release: 0 Summary: Modern UI for Ansible License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.0XE2VV/_old 2026-07-23 23:14:22.928788238 +0200 +++ /var/tmp/diff_new_pack.0XE2VV/_new 2026-07-23 23:14:22.932788379 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/ansible-semaphore/semaphore.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">refs/tags/v2.18.26</param> + <param name="revision">refs/tags/v2.18.28</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.0XE2VV/_old 2026-07-23 23:14:22.960789364 +0200 +++ /var/tmp/diff_new_pack.0XE2VV/_new 2026-07-23 23:14:22.964789504 +0200 @@ -3,6 +3,6 @@ <param name="url">https://github.com/ansible-semaphore/semaphore</param> <param name="changesrevision">8a4dcf0868af718aaa5871368a3247dd622521f4</param></service><service name="tar_scm"> <param name="url">https://github.com/ansible-semaphore/semaphore.git</param> - <param name="changesrevision">ee781a032ccb58c61de6b9a70993f9b6dc77dcf8</param></service></servicedata> + <param name="changesrevision">33874e063dd9d7dc441e11f7fbfc24c0c28b270f</param></service></servicedata> (No newline at EOF) ++++++ semaphore-2.18.26.obscpio -> semaphore-2.18.28.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/semaphore-2.18.26/api/projects/templates.go new/semaphore-2.18.28/api/projects/templates.go --- old/semaphore-2.18.26/api/projects/templates.go 2026-07-12 13:37:09.000000000 +0200 +++ new/semaphore-2.18.28/api/projects/templates.go 2026-07-22 14:24:43.000000000 +0200 @@ -106,11 +106,6 @@ return } - if _, ok := util.Config.Apps[string(newTemplate.App)]; !ok { - helpers.WriteErrorStatus(w, "Invalid app id: "+string(newTemplate.App), http.StatusBadRequest) - return - } - // Check workspace and create it if required. if newTemplate.App.IsTerraform() { var inv db.Inventory diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/semaphore-2.18.26/db/Template.go new/semaphore-2.18.28/db/Template.go --- old/semaphore-2.18.26/db/Template.go 2026-07-12 13:37:09.000000000 +0200 +++ new/semaphore-2.18.28/db/Template.go 2026-07-22 14:24:43.000000000 +0200 @@ -4,6 +4,7 @@ "encoding/json" "github.com/semaphoreui/semaphore/pkg/common_errors" + "github.com/semaphoreui/semaphore/util" log "github.com/sirupsen/logrus" ) @@ -212,6 +213,17 @@ if tpl.RunnerTag != nil && *tpl.RunnerTag == "" { return &ValidationError{"template runner tag can not be empty"} } + + // Reject apps that are not in the administrator-configured whitelist, otherwise + // an unknown app becomes a ShellApp that executes string(App) as a system binary + // (arbitrary command execution). util.Config is nil in some unit tests; an empty + // app is the legacy default and runs no command, so both are skipped. + if tpl.App != "" { + if _, ok := util.Config.Apps[string(tpl.App)]; !ok { + return &ValidationError{"invalid app: " + string(tpl.App)} + } + } + switch tpl.App { case AppAnsible: if tpl.InventoryID == nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/semaphore-2.18.26/db/Template_app_test.go new/semaphore-2.18.28/db/Template_app_test.go --- old/semaphore-2.18.26/db/Template_app_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/semaphore-2.18.28/db/Template_app_test.go 2026-07-22 14:24:43.000000000 +0200 @@ -0,0 +1,29 @@ +package db + +import ( + "testing" + + "github.com/semaphoreui/semaphore/util" + "github.com/stretchr/testify/assert" +) + +func TestTemplate_Validate_App(t *testing.T) { + orig := util.Config + defer func() { util.Config = orig }() + + util.Config = &util.ConfigType{ + Apps: map[string]util.App{"bash": {Active: true}}, + } + + // Arbitrary binary not in the whitelist must be rejected before persisting. + tpl := &Template{Name: "rce", Playbook: "-c", App: "/bin/sh"} + assert.EqualError(t, tpl.Validate(), "invalid app: /bin/sh") + + // Whitelisted app is accepted. + ok := &Template{Name: "legit", Playbook: "script.sh", App: "bash"} + assert.NoError(t, ok.Validate()) + + // Empty legacy app runs no command and stays allowed. + empty := &Template{Name: "legacy", Playbook: "site.yml", App: ""} + assert.NoError(t, empty.Validate()) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/semaphore-2.18.26/db/sql/SqlDb.go new/semaphore-2.18.28/db/sql/SqlDb.go --- old/semaphore-2.18.26/db/sql/SqlDb.go 2026-07-12 13:37:09.000000000 +0200 +++ new/semaphore-2.18.28/db/sql/SqlDb.go 2026-07-22 14:24:43.000000000 +0200 @@ -105,6 +105,9 @@ } func (d *SqlDbConnection) Close() { + if d.sql.Db == nil { + return + } err := d.sql.Db.Close() if err != nil { panic(err) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/semaphore-2.18.26/web/src/components/ScheduleForm.vue new/semaphore-2.18.28/web/src/components/ScheduleForm.vue --- old/semaphore-2.18.26/web/src/components/ScheduleForm.vue 2026-07-12 13:37:09.000000000 +0200 +++ new/semaphore-2.18.28/web/src/components/ScheduleForm.vue 2026-07-22 14:24:43.000000000 +0200 @@ -607,7 +607,24 @@ } }, - refreshCheckboxes() { + async validateCronFormat(cronFormat) { + try { + await axios({ + method: 'post', + url: `/api/project/${this.projectId}/schedules/validate`, + responseType: 'json', + data: { + project_id: this.projectId, + cron_format: cronFormat, + }, + }); + return null; + } catch (err) { + return getErrorMessage(err); + } + }, + + async refreshCheckboxes() { if (this.type === 'run_at') { this.cronFormatError = null; this.disableRawCron = false; @@ -624,13 +641,28 @@ this.cronFormatError = null; this.disableRawCron = false; + const cronFormat = this.item.cron_format; + const cronError = await this.validateCronFormat(cronFormat); + + if (cronFormat !== this.item.cron_format) { + return; // the value changed while validating, ignore stale result + } + + if (cronError != null) { + this.cronFormatError = cronError; + this.rawCron = true; + this.disableRawCron = true; + return; + } + let cron; try { cron = CronExpressionParser.parse(this.item.cron_format, { tz: this.timezone, }); - } catch (err) { - this.cronFormatError = getErrorMessage(err); + } catch { + // Valid on the backend but not parseable by cron-parser + // (e.g. @hourly) — show it in raw mode without an error. this.rawCron = true; this.disableRawCron = true; return; ++++++ semaphore.obsinfo ++++++ --- /var/tmp/diff_new_pack.0XE2VV/_old 2026-07-23 23:14:24.240834377 +0200 +++ /var/tmp/diff_new_pack.0XE2VV/_new 2026-07-23 23:14:24.252834799 +0200 @@ -1,5 +1,5 @@ name: semaphore -version: 2.18.26 -mtime: 1783856229 -commit: ee781a032ccb58c61de6b9a70993f9b6dc77dcf8 +version: 2.18.28 +mtime: 1784723083 +commit: 33874e063dd9d7dc441e11f7fbfc24c0c28b270f ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/semaphore/vendor.tar.gz /work/SRC/openSUSE:Factory/.semaphore.new.2004/vendor.tar.gz differ: char 150, line 2 ++++++ web-2.18.26.tar.gz -> web-2.18.28.tar.gz ++++++ /work/SRC/openSUSE:Factory/semaphore/web-2.18.26.tar.gz /work/SRC/openSUSE:Factory/.semaphore.new.2004/web-2.18.28.tar.gz differ: char 31, line 1
