system: You are an expert security code reviewer. You will be shown a source code file along with a catalog of candidate CWE (Common Weakness Enumeration) categories with their official MITRE names. Your task is to list every distinct CWE from that catalog that is actually present in the code. The catalog is comprehensive for this dataset -- the answer is a (possibly small) subset of it.

OUTPUT FORMAT: Respond with a comma-separated list of CWE IDs in the form `CWE-N`, sorted in ascending numeric order, wrapped in a single \boxed{...}. Examples: `\boxed{CWE-79}` for one, `\boxed{CWE-22,CWE-79,CWE-327}` for three. Output the boxed answer ONLY -- no explanation, no other text.

user: ```python
"""
Module for creating Song objects by interacting with Spotify API
or by parsing a query.

To use this module you must first initialize the SpotifyClient.
"""

import json
import concurrent.futures

from typing import List, Optional

from spotdl.types import Playlist, Album, Artist, Saved
from spotdl.types.song import SongList, Song


class QueryError(Exception):
    """
    Base class for all exceptions related to query.
    """


def get_search_results(search_term: str) -> List[Song]:
    """
    Creates a list of Song objects from a search term.

    ### Arguments
    - search_term: the search term to use

    ### Returns
    - a list of Song objects
    """

    return Song.list_from_search_term(search_term)


def parse_query(
    query: List[str],
    threads: int = 1,
) -> List[Song]:
    """
    Parse query and return list containing song object

    ### Arguments
    - query: List of strings containing query
    - threads: Number of threads to use

    ### Returns
    - List of song objects
    """

    songs: List[Song] = get_simple_songs(query)

    results = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=threads) as executor:
        for song in executor.map(reinit_song, songs):
            results.append(song)

    return results


def create_empty_song(
    name: Optional[str] = None,
    artists: Optional[List[str]] = None,
    album_name: Optional[str] = None,
    album_artist: Optional[str] = None,
    genres: Optional[List[str]] = None,
    disc_number: Optional[int] = None,
    disc_count: Optional[int] = None,
    duration: Optional[int] = None,
    year: Optional[int] = None,
    date: Optional[str] = None,
    track_number: Optional[int] = None,
    tracks_count: Optional[int] = None,
    isrc: Optional[str] = None,
    song_id: Optional[str] = None,
    cover_url: Optional[str] = None,
    explicit: Optional[bool] = None,
    publisher: Optional[str] = None,
    url: Optional[str] = None,
    copyright_text: Optional[str] = None,
    download_url: Optional[str] = None,
    song_list: Optional["SongList"] = None,
) -> Song:
    """
    Create an empty song.

    ### Arguments
    - name: Name of the song
    - artists: List of artists
    - album_name: Name of the album
    - album_artist: Name of the album artist
    - genres: List of genres
    - disc_number: Disc number
    - disc_count: Disc count
    - duration: Duration of the song in seconds
    - year: Year of release
    - date: Date of release
    - track_number: Track number
    - tracks_count: Number of tracks
    - isrc: ISRC code
    - song_id: Spotify song ID
    - cover_url: URL of the cover art
    - explicit: Explicit flag
    - publisher: Publisher
    - url: URL of the song
    - copyright_text: Copyright text
    - download_url: Download URL
    - song_list: Song list

    ### Returns
    - Song object
    """

    return Song(
        name=name,  # type: ignore
        artists=artists,  # type: ignore
        artist=None if artists is None else artists[0],  # type: ignore
        album_name=album_name,  # type: ignore
        album_artist=album_artist,  # type: ignore
        genres=genres,  # type: ignore
        disc_number=disc_number,  # type: ignore
        disc_count=disc_count,  # type: ignore
        duration=duration,  # type: ignore
        year=year,  # type: ignore
        date=date,  # type: ignore
        track_number=track_number,  # type: ignore
        tracks_count=tracks_count,  # type: ignore
        isrc=isrc,  # type: ignore
        song_id=song_id,  # type: ignore
        cover_url=cover_url,  # type: ignore
        explicit=explicit,  # type: ignore
        publisher=publisher,  # type: ignore
        url=url,  # type: ignore
        copyright_text=copyright_text,
        download_url=download_url,
        song_list=song_list,
    )


def get_simple_songs(
    query: List[str],
) -> List[Song]:
    """
    Parse query and return list containing simple song objects

    ### Arguments
    - query: List of strings containing query

    ### Returns
    - List of simple song objects
    """

    songs: List[Song] = []
    lists: List[SongList] = []
    for request in query:
        if (
            "youtube.com/watch?v=" in request
            or "youtu.be/" in request
            and "open.spotify.com" in request
            and "track" in request
            and "|" in request
        ):
            split_urls = request.split("|")
            if (
                len(split_urls) <= 1
                or "youtube" not in split_urls[0]
                and "youtu.be" not in split_urls[0]
                or "spotify" not in split_urls[1]
            ):
                raise QueryError(
                    'Incorrect format used, please use "YouTubeURL|SpotifyURL"'
                )

            songs.append(
                create_empty_song(url=split_urls[1], download_url=split_urls[0])
            )
        elif "open.spotify.com" in request and "track" in request:
            songs.append(create_empty_song(url=request))  # type: ignore
        elif "open.spotify.com" in request and "playlist" in request:
            lists.append(Playlist.create_basic_list(request))
        elif "open.spotify.com" in request and "album" in request:
            lists.append(Album.create_basic_list(request))
        elif "open.spotify.com" in request and "artist" in request:
            lists.append(Artist.create_basic_list(request))
        elif "album:" in request:
            lists.append(Album.from_search_term(request))
        elif request == "saved":
            lists.append(Saved.create_basic_list())
        elif request.endswith(".spotdl"):
            with open(request, "r", encoding="utf-8") as save_file:
                for track in json.load(save_file):
                    # Append to songs
                    songs.append(Song.from_dict(track))
        else:
            songs.append(Song.from_search_term(request))

    for song_list in lists:
        songs.extend(
            [create_empty_song(url=url, song_list=song_list) for url in song_list.urls]
        )  # type: ignore

    return songs


def reinit_song(song: Song, playlist_numbering: bool = False) -> Song:
    """
    Update song object with new data
    from Spotify

    ### Arguments
    - song: Song object
    - playlist_numbering: bool, default value is False

    ### Returns
    - Updated song object
    """

    data = song.json
    new_data = Song.from_url(data["url"]).json
    data.update((k, v) for k, v in new_data.items() if v is not None)

    if data.get("song_list"):
        # Reinitialize the correct song list object
        if song.song_list:
            song_list = song.song_list.__class__(**data["song_list"])
            data["song_list"] = song_list
            data["list_position"] = song_list.urls.index(song.url)
            if playlist_numbering:
                data["track_number"] = data["list_position"] + 1
                data["tracks_count"] = len(song_list.urls)
                data["album_name"] = song_list.name
                if isinstance(song_list, Playlist):
                    data["album_artist"] = song_list.author_name
                    data["cover_url"] = song_list.cover_url
                data["disc_number"] = 1
                data["disc_count"] = 1

    # return reinitialized song object
    return Song(**data)

```

Candidate CWE catalog (every CWE that appears anywhere in this dataset):
  - CWE-20: Improper Input Validation
  - CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
  - CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')
  - CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
  - CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  - CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
  - CWE-94: Improper Control of Generation of Code ('Code Injection')
  - CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Request/Response Splitting')
  - CWE-116: Improper Encoding or Escaping of Output
  - CWE-117: Improper Output Neutralization for Logs
  - CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
  - CWE-209: Generation of Error Message Containing Sensitive Information
  - CWE-215: Insertion of Sensitive Information Into Debugging Code
  - CWE-295: Improper Certificate Validation
  - CWE-312: Cleartext Storage of Sensitive Information
  - CWE-326: Inadequate Encryption Strength
  - CWE-327: Use of a Broken or Risky Cryptographic Algorithm
  - CWE-377: Insecure Temporary File
  - CWE-502: Deserialization of Untrusted Data
  - CWE-601: URL Redirection to Untrusted Site ('Open Redirect')
  - CWE-611: Improper Restriction of XML External Entity Reference
  - CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute
  - CWE-643: Improper Neutralization of Data within XPath Expressions ('XPath Injection')
  - CWE-730: OWASP Top Ten 2004 Category A9 - Denial of Service
  - CWE-732: Incorrect Permission Assignment for Critical Resource
  - CWE-776: Improper Restriction of Recursive Entity References in DTDs ('XML Entity Expansion')
  - CWE-918: Server-Side Request Forgery (SSRF)
  - CWE-943: Improper Neutralization of Special Elements in Data Query Logic
  - CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag
  - CWE-1333: Inefficient Regular Expression Complexity

List every distinct CWE from the catalog above that is actually present in this code.
Answer: CWE-20