πŸ•ΆοΈ
VICEINTELPRO
GitHub: HorrorClause
  • In Tenebris Videmus
  • 🚩CTFs
    • πŸ’ΎHack the Box
      • 🏫Academy
        • Command Injection Assessment
        • XSS Assessment
        • Web Attacks Assessment
    • Try Hack Me
      • In Progress
  • πŸ“–Documents
  • πŸ‘¨β€πŸ«HOW-TOs
    • Obisidian How-To
    • Setup Mandiant FLARE VM
  • πŸ“‘Security Fundamentals
    • Security Controls
      • Physical Security
      • Endpoint Security
      • Email Security
      • Network Security
      • AAA Controls
    • Networking 101
      • OSI Model
      • Network Fundamentals
      • Network Devices
      • Network Tools
      • Protocols and Ports
    • πŸ‘¨β€πŸ’ΌManagement Principles
      • Risk
      • Policies and Procedures
      • Compliance and Frameworks
      • Change and Patch Management
  • πŸ›‘οΈSecurity Concepts
    • ⚠️Risk Assessment Models
      • DREAD Risk Assessment Model
      • STRIDE Threat Model
      • Common Vulnerability Scoring System (CVSS)
    • Pentesting
      • Common Terms
      • AV Identification-Evasion
      • Introduction to Payloads
      • Automating Payloads & Delivery with Metasploit
      • Shells Jack Us In, Payloads Deliver Us Shells
      • Web Shells
      • Pentesting Overview
      • Penetration Testing Process
    • πŸ›Vulnerability Assessment
      • Common Vulnerabilities and Exposures (CVE)
      • Common Vulnerability Scoring System (CVSS)
      • Assessment Standards
      • Vulnerability Assessment
      • Vulnerability Scanning
      • Reporting
      • 🎯Nessus
        • Getting Started with Nessus
        • Nessus Scan
        • Working with Nessus Scan Output
        • Advanced Settings
        • Scanning Issues
      • 🦴OpenVAS (Greenbone)
        • Getting Started with OpenVAS
        • OpenVAS
        • Exporting Results
    • Passwords
      • Password Managers
      • Password Policies
      • Password Security Fundamentals
    • Frameworks
    • GRC
    • Logon Types
    • What is Dev-Null ?
  • βš”οΈOffensive Security
    • OSINT
      • OSINT - Websites
      • Google Dorks
    • πŸ”«Attacking Common Services
      • The Concept of Attacks
      • Interacting with Common Services
      • Finding Sensitive Information
      • Attacking DNS
      • Attacking Email Services
      • Attacking FTP
      • Attacking RDP
      • Attacking SMB
      • Attacking SQL Databases
      • Cheat Sheet - Attacking Common Services
      • Service Misconfigurations
    • πŸ”ͺAttacking Web Apps with Ffuf
      • Web Fuzzing
      • Directory Fuzzing
      • Page Fuzzing
      • Recursive Fuzzing
      • DNS Records
      • Sub-domain Fuzzing
      • Vhost Fuzzing
      • Filtering Results
      • Parameter Fuzzing - GET
      • Parameter Fuzzing - POST
      • Value Fuzzing
    • ☁️Cloud
      • AWS
        • AWS S3 Buckets
    • πŸ’‰Command Injection
      • Command Injection Cheat Sheet
      • Intro to Command Injections
      • Detection
      • Injecting Commands
      • Other Injection Operators
      • Identifying Filters
      • Bypassing Space Filters
      • Bypassing Other Blacklisted Characters
      • Bypassing Blacklisted Commands
      • Advanced Command Obfuscation
      • Evasion Tools
      • Command Injection Prevention
    • Containers
      • Docker
    • ❌Cross-Site Scripting (XSS)
      • Introduction to XSS
      • Stored XSS
      • Reflected XSS
      • DOM XSS
      • XSS Discovery
      • Defacing
      • Phishing
      • Session Hijacking
      • XSS Prevention
    • Directory Busting
      • DirB
      • DirBuster
      • Ffuf
      • Gobuster
    • πŸ…°οΈDNS
      • DNSRecon
      • Fierce
    • File Inclusion
      • Local File Inclusion Cheatsheet
      • Intro to File Inclusion
      • Local File Inclusion (LFI)
      • Basic Bypass
      • PHP Filters
      • PHP Wrappers
      • Remote File Inclusion (RFI)
      • LFI and File Uploads
      • Log Poisoning
      • Automated Scanning
      • File Inclusion Prevention
    • File Transfers
      • Transferring Files
      • File Transfer - Quick Commands
      • Living off the Land
      • Windows File Transfer Methods
      • Linux File Transfer Methods
      • Catching Files over HTTP(S)
      • Transferring Files with Code
      • Miscellaneous File Transfer Methods
      • Protected File Transfers
      • Mounting Encrypted VHD Drives
      • Mounting VHD in Kali
      • File Transfer Detection
    • File Upload Attacks
      • File Upload Cheatsheet
      • Absent Validation
      • Upload Exploitation
      • Client-Side Validation
      • Blacklist Filters
      • Whitelist Filters
      • Type Filters
      • Limited File Uploads
      • Other Upload Attacks
      • Preventing File Upload Vulnerabilities
    • πŸ‘£Footprinting
      • Linux Remote Management Protocols
      • Windows Remote Management Protocols
      • Enumeration
        • Enumeration Methodology
        • πŸ–₯️Host Based
          • Quick Commands
          • DNS
          • FTP
          • IMAP-POP3
          • IPMI
          • MSSQL
          • MySQL
          • NFS
          • Oracle TNS
          • SMB
  • Powershell
    • Powershell CheatSheet
  • Python
    • Map
    • Anonymous Functions
    • Recursion
      • ZipMap
      • Nested Sum
      • Recursion on a Tree
      • Count Nested Levels
      • Longest Word
    • Function Transformations
      • More Transformations
      • Why Transform?
    • Closures
    • Currying
    • Decorators
    • Sum Types
    • Enums
    • Match
    • Regex
  • Kusto (KQL)
    • SQL and KQL Comparison
    • Using the Where and Sort Operators
    • KQL Queries
  • HTML
  • Insecure File Uploads
Powered by GitBook
On this page
  • Working With Enums
  • Assignment
  • Solution
  1. Python

Match

PreviousEnumsNextRegex

Last updated 2 months ago

Let's take another look at our example from the previous lesson:

Color = Enum("Color", ["RED", "GREEN", "BLUE"])

Working With Enums

Python has a match statement that tends to be a lot cleaner than a series of if/else/elif statements when we're working with a fixed set of possible values (like a sum type, or more specifically an enum):

def get_hex(color):
    match color:
        case Color.RED:
            return "#FF0000"
        case Color.GREEN:
            return "#00FF00"
        case Color.BLUE:
            return "#0000FF"

        # default case
        # (invalid Color)
        case _:
            return "#FFFFFF"

If you have two values to match, you can use a tuple:

def get_hex(color, shade):
    match (color, shade):
        case (Color.RED, Shade.LIGHT):
            return "#FFAAAA"
        case (Color.RED, Shade.DARK):
            return "#AA0000"
        case (Color.GREEN, Shade.LIGHT):
            return "#AAFFAA"
        case (Color.GREEN, Shade.DARK):
            return "#00AA00"
        case (Color.BLUE, Shade.LIGHT):
            return "#AAAAFF"
        case (Color.BLUE, Shade.DARK):
            return "#0000AA"

        # default case
        # (invalid combination)
        case _:
            return "#FFFFFF"

The value we want to compare is set after the match keyword, which is then compared against different cases/patterns. If a match is found, the code in the block is executed.

Assignment

Complete the convert_format function. Using the enum DocFormat, it should support 3 types of conversions:

From MD to HTML:

Assume the content is a single h1 tag in markdown syntax - it's a single string representing a line. Replace the leading # with an <h1> and add a </h1> to the end.

# This is a heading -> <h1>This is a heading</h1>

From TXT to PDF:

Simply add a [PDF] tag to the beginning and end of the content. Notice the spaces between [PDF] tags and the content:

This is some text -> [PDF] This is some text [PDF]

From HTML to MD:

Replace any <h1> tags with # and remove any </h1> tags.

<h1>This is a heading</h1> -> # This is a heading

Any other conversion:

If the input format is invalid, raise an Exception with the string invalid type

Solution

from enum import Enum


class DocFormat(Enum):
    PDF = 1
    TXT = 2
    MD = 3
    HTML = 4


# don't touch above this line


def convert_format(content, from_format, to_format):
    match (from_format,to_format):
        case (DocFormat.MD, DocFormat.HTML):
            return f"<h1>{content.lstrip('# ')}</h1>"
        case (DocFormat.TXT, DocFormat.PDF):
            return f'[PDF] {content} [PDF]'
        case (DocFormat.HTML, DocFormat.MD):
            return f'# {content.lstrip("<h1>").rstrip("</h1>")}'
    
        case _:    
            raise Exception("invalid type")

Why this works

The solution works because it correctly applies pattern matching (match-case) to handle different document format conversions while ensuring proper transformations for MD -> HTML, TXT -> PDF, and HTML -> MD. Here’s a breakdown of why it’s correct:


1️⃣ DocFormat Enum Ensures Valid Inputs

class DocFormat(Enum):
    PDF = 1
    TXT = 2
    MD = 3
    HTML = 4
  • Enum restricts valid formats to PDF, TXT, MD, and HTML, ensuring that convert_format only works with these predefined document types.

  • This makes checking from_format and to_format more structured and type-safe.


2️⃣ Pattern Matching Ensures the Right Conversion Logic

match (from_format, to_format):
  • This is a tuple pattern match, which checks the (from_format, to_format) pair.


3️⃣ Case 1: Markdown (MD) to HTML (HTML)

case (DocFormat.MD, DocFormat.HTML):
    return f"<h1>{content.lstrip('# ')}</h1>"
  • Transformation Logic:

    • Markdown # This is a heading should become <h1>This is a heading</h1>.

    • lstrip("# ") removes the leading # from the Markdown heading.

    • Wraps the remaining content in <h1> and </h1>.

βœ… Example:

convert_format("# Welcome", DocFormat.MD, DocFormat.HTML)
# Output: "<h1>Welcome</h1>"

4️⃣ Case 2: Text (TXT) to PDF (PDF)

case (DocFormat.TXT, DocFormat.PDF):
    return f"[PDF] {content} [PDF]"
  • Transformation Logic:

    • The input text needs to be enclosed with [PDF] and [PDF] (including spaces).

βœ… Example:

convert_format("Some text", DocFormat.TXT, DocFormat.PDF)
# Output: "[PDF] Some text [PDF]"

5️⃣ Case 3: HTML (HTML) to Markdown (MD)

case (DocFormat.HTML, DocFormat.MD):
    return f"# {content.lstrip('<h1>').rstrip('</h1>')}"
  • Transformation Logic:

    • Removes <h1> and </h1> tags.

    • Adds # at the beginning to convert back to Markdown.

βœ… Example:

convert_format("<h1>Title</h1>", DocFormat.HTML, DocFormat.MD)
# Output: "# Title"

6️⃣ Handling Invalid Conversions

case _:    
    raise Exception("invalid type")
  • If none of the valid cases match, an exception is raised.

  • This prevents incorrect conversions (e.g., MD -> PDF or TXT -> HTML).

βœ… Example:

convert_format("Random text", DocFormat.MD, DocFormat.PDF)
# Raises Exception: "invalid type"

Why This Works Well

βœ… 1. Pattern Matching is Clean and Readable

  • The match-case structure avoids multiple if-elif checks and makes the conversion logic explicit.

βœ… 2. Enum Ensures Strict Format Matching

  • No risk of passing random strings like "Markdown" or "pdf", since DocFormat enforces valid values.

βœ… 3. Proper String Transformations

  • Uses lstrip() and rstrip() correctly for Markdown/HTML transformations.

  • Adds [PDF] tags with proper spacing.

βœ… 4. Error Handling is Explicit

  • If an invalid format conversion is attempted, an exception is raised instead of returning incorrect output.

Enum