@@ -220,6 +220,55 @@ if [ "$EXPECTED" != "$ACTUAL" ]; then
220220fi
221221echo " Checksum verified."
222222
223+ # Validate the complete archive namespace before extraction. Current and legacy
224+ # release assets use the same four-member root layout; anything outside that
225+ # closed set is a release-integrity failure, not a sidecar to ignore.
226+ if [ " $OS " = " windows" ]; then
227+ ARCHIVE_BINARY=" codebase-memory-mcp.exe"
228+ ARCHIVE_INSTALLER=" install.ps1"
229+ else
230+ ARCHIVE_BINARY=" codebase-memory-mcp"
231+ ARCHIVE_INSTALLER=" install.sh"
232+ fi
233+ ARCHIVE_MEMBERS_FILE=" $DLDIR /archive-members.txt"
234+ if [ " $EXT " = " zip" ]; then
235+ if ! unzip -Z1 " $DLDIR /$ARCHIVE " > " $ARCHIVE_MEMBERS_FILE " ; then
236+ echo " error: could not enumerate release archive" >&2
237+ exit 1
238+ fi
239+ else
240+ if ! tar -tzf " $DLDIR /$ARCHIVE " > " $ARCHIVE_MEMBERS_FILE " ; then
241+ echo " error: could not enumerate release archive" >&2
242+ exit 1
243+ fi
244+ fi
245+
246+ BINARY_MEMBERS=0
247+ LICENSE_MEMBERS=0
248+ INSTALLER_MEMBERS=0
249+ NOTICE_MEMBERS=0
250+ ARCHIVE_MEMBER_COUNT=0
251+ while IFS= read -r member || [ -n " $member " ]; do
252+ ARCHIVE_MEMBER_COUNT=$(( ARCHIVE_MEMBER_COUNT + 1 ))
253+ case " $member " in
254+ " $ARCHIVE_BINARY " ) BINARY_MEMBERS=$(( BINARY_MEMBERS + 1 )) ;;
255+ LICENSE) LICENSE_MEMBERS=$(( LICENSE_MEMBERS + 1 )) ;;
256+ " $ARCHIVE_INSTALLER " ) INSTALLER_MEMBERS=$(( INSTALLER_MEMBERS + 1 )) ;;
257+ THIRD_PARTY_NOTICES.md) NOTICE_MEMBERS=$(( NOTICE_MEMBERS + 1 )) ;;
258+ * )
259+ echo " error: release archive contains unexpected member: $member " >&2
260+ exit 1
261+ ;;
262+ esac
263+ done < " $ARCHIVE_MEMBERS_FILE "
264+
265+ if [ " $BINARY_MEMBERS " -ne 1 ] || [ " $LICENSE_MEMBERS " -ne 1 ] ||
266+ [ " $INSTALLER_MEMBERS " -ne 1 ] || [ " $NOTICE_MEMBERS " -ne 1 ] ||
267+ [ " $ARCHIVE_MEMBER_COUNT " -ne 4 ]; then
268+ echo " error: release archive does not match the exact member set" >&2
269+ exit 1
270+ fi
271+
223272# Extract
224273echo " Extracting..."
225274if [ " $EXT " = " zip" ]; then
@@ -228,8 +277,16 @@ else
228277 tar --no-same-owner -xzf " $DLDIR /$ARCHIVE " -C " $DLDIR "
229278fi
230279
231- DLBIN=" $DLDIR /codebase-memory-mcp"
232- if [ ! -f " $DLBIN " ]; then
280+ for extracted_member in " $ARCHIVE_BINARY " LICENSE " $ARCHIVE_INSTALLER " \
281+ THIRD_PARTY_NOTICES.md; do
282+ if [ ! -f " $DLDIR /$extracted_member " ] || [ -L " $DLDIR /$extracted_member " ]; then
283+ echo " error: release member is not a regular file: $extracted_member " >&2
284+ exit 1
285+ fi
286+ done
287+
288+ DLBIN=" $DLDIR /$ARCHIVE_BINARY "
289+ if [ ! -f " $DLBIN " ] || [ -L " $DLBIN " ]; then
233290 echo " error: binary not found after extraction" >&2
234291 exit 1
235292fi
0 commit comments