Skip to content

Commit

Permalink
No build directives in generated spec parts
Browse files Browse the repository at this point in the history
Many things need to be known before the build can be started. Make
declaring these sections or directives an error when encountered parsing
the generated Spec parts.

Resolves: rpm-software-management#2693
  • Loading branch information
ffesti committed Feb 19, 2024
1 parent e30eff3 commit 55c12c3
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 5 deletions.
39 changes: 35 additions & 4 deletions build/parsePreamble.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,9 @@ static int addBuildOption(rpmSpec spec, const char *sect, const char *opt)
return rc;
}

static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
const char *macro, const char *lang)
static rpmRC handlePreambleTag(rpmSpec spec, enum parseStages stage,
Package pkg, rpmTagVal tag,
const char *macro, const char *lang)
{
char * field = spec->line;
char * end;
Expand Down Expand Up @@ -1009,6 +1010,14 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
BANames = _free(BANames);
goto exit;
}
if (stage == GENERATED &&
(BACount != 1 || !rstreq(BANames[0], "noarch"))) {
rpmlog(RPMLOG_ERR,
_("line %d: Only noarch is allowed after the build: %s\n"),
spec->lineNum, spec->line);
BANames = _free(BANames);
goto exit;
}
spec->BACount = BACount;
spec->BANames = BANames;
} else {
Expand Down Expand Up @@ -1179,7 +1188,7 @@ static int findPreambleTag(rpmSpec spec,rpmTagVal * tag,
return 0;
}

int parsePreamble(rpmSpec spec, int initialPackage)
int parsePreamble(rpmSpec spec, int initialPackage, enum parseStages stage)
{
int nextPart = PART_ERROR;
int res = PART_ERROR; /* assume failure */
Expand Down Expand Up @@ -1248,7 +1257,29 @@ int parsePreamble(rpmSpec spec, int initialPackage)
spec->lineNum, spec->line);
goto exit;
}
if (handlePreambleTag(spec, pkg, tag, macro, lang)) {
if (stage == GENERATED) {
switch (tag) {
case RPMTAG_SOURCE:
case RPMTAG_PATCH:
case RPMTAG_NOSOURCE:
case RPMTAG_NOPATCH:
case RPMTAG_EXCLUDEARCH:
case RPMTAG_EXCLUSIVEARCH:
case RPMTAG_EXCLUDEOS:
case RPMTAG_EXCLUSIVEOS:
case RPMTAG_BUILDROOT:
case RPMTAG_BUILDCONFLICTS:
case RPMTAG_BUILDOPTION:
case RPMTAG_BUILDPREREQ:
case RPMTAG_BUILDREQUIRES:
case RPMTAG_BUILDSYSTEM:
rpmlog(RPMLOG_ERR, _("line %d: Tag not allowed after build is done: %s\n"),
spec->lineNum, spec->line);
goto exit;
default: ;
}
}
if (handlePreambleTag(spec, stage, pkg, tag, macro, lang)) {
goto exit;
}
if (spec->BANames && !spec->recursing) {
Expand Down
33 changes: 32 additions & 1 deletion build/parseSpec.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ int isPart(const char *line)
return (p->token ? p->part : PART_NONE);
}

static const char * partName(int part)
{
const struct PartRec *p;

for (p = partList; p->token != NULL; p++) {
if (p->part == part) {
return p->token;
}
}
return NULL;
}

/**
*/
static int matchTok(const char *token, const char *line)
Expand Down Expand Up @@ -1022,7 +1034,7 @@ static rpmRC parseSpecSection(rpmSpec *specptr, enum parseStages stage)
parsePart = parseEmpty(spec, prevParsePart);
break;
case PART_PREAMBLE:
parsePart = parsePreamble(spec, initialPackage);
parsePart = parsePreamble(spec, initialPackage, stage);
initialPackage = 0;
break;
case PART_PATCHLIST:
Expand Down Expand Up @@ -1111,6 +1123,25 @@ static rpmRC parseSpecSection(rpmSpec *specptr, enum parseStages stage)
goto errxit;
}

if (stage == GENERATED) {
switch (parsePart) {
case PART_PREP:
case PART_BUILD:
case PART_INSTALL:
case PART_CHECK:
case PART_CLEAN: /* ???? */
case PART_BUILDARCHITECTURES:
case PART_PATCHLIST:
case PART_SOURCELIST:
case PART_BUILDREQUIRES:
case PART_CONF:
rpmlog(RPMLOG_ERR, _("Section %s is not allowed after build is done!\n"), partName(parsePart));
goto errxit;
break;
default:
;
}
}
if (parsePart == PART_BUILDARCHITECTURES) {
int index;
int x;
Expand Down
11 changes: 11 additions & 0 deletions docs/manual/dynamic_specs.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,14 @@ interpreted right away.

[Example](https://github.com/rpm-software-management/rpm/blob/master/tests/data/SPECS/dynamic.spec)
from our tests set.

As dynamic spec parts are generate during build they cannot include
directives that are needed for or influence building. This includes
all build scripts, sources and patches, Build dependencies, tags
regarding the build environment (**ExcludeArch**, **ExclusiveArch**,
**ExcludeOS**, **ExclusiveOS**), **BuildArch** except for declaring
sub packages **noarch** and **BuildSystem**. These will create an
error if encountered in a dynamically generated spec part.

While declaring macros used in the build scripts are not an error they
won't have an influence on the build for obvious reasons.
2 changes: 2 additions & 0 deletions tests/data/SPECS/dynamic.spec
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ echo "LicenseToKill: True" >> %{specpartsdir}/mainpkg.specpart
echo "%package docs" >> %{specpartsdir}/docs.specpart
%{?!FAIL:echo "Summary: Documentation for dynamic spec" >> %{specpartsdir}/docs.specpart}
echo "BuildArch: noarch" >> %{specpartsdir}/docs.specpart
%{?FORBIDDENTAG:echo "BuildRequires: python3" >> %{specpartsdir}/docs.specpart}
%{?FORBIDDENSECTION:echo "%check" >> %{specpartsdir}/docs.specpart}
echo "%description docs" >> %{specpartsdir}/docs.specpart
echo "Test for dynamically generated spec files" >> %{specpartsdir}/docs.specpart
echo "%files docs" >> $RPM_SPECPARTS_DIR/docs.specpart
Expand Down
34 changes: 34 additions & 0 deletions tests/rpmbuild.at
Original file line number Diff line number Diff line change
Expand Up @@ -2764,6 +2764,40 @@ error: parsing failed

RPMTEST_CLEANUP

# ------------------------------
# Check failing dynamic spec generation
AT_SETUP([rpmbuild with dynamic spec generation fail])
AT_KEYWORDS([build])
RPMDB_INIT
RPMTEST_CHECK([

runroot rpmbuild --quiet -D "FULLDYNAMIC 1" -D "FORBIDDENSECTION 1" -ba /data/SPECS/dynamic.spec
],
[1],
[],
[error: Section %check is not allowed after build is done!
error: parsing failed
])

RPMTEST_CLEANUP

# ------------------------------
# Check failing dynamic spec generation
AT_SETUP([rpmbuild with dynamic spec generation fail])
AT_KEYWORDS([build])
RPMDB_INIT
RPMTEST_CHECK([

runroot rpmbuild --quiet -D "FULLDYNAMIC 1" -D "FORBIDDENTAG 1" -ba /data/SPECS/dynamic.spec
],
[1],
[],
[error: line 4: Tag not allowed after build is done: BuildRequires: python3
error: parsing failed
])

RPMTEST_CLEANUP


# ------------------------------
# Check source name with space
Expand Down

0 comments on commit 55c12c3

Please sign in to comment.