Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions WEEK03/프로그래머스_[3차] 방금그곡/Raven.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
func solution(_ m:String, _ musicinfos:[String]) -> String {
var result = "(None)"
var resultPlayTime = 0
var resultStartTime = 0

for info in musicinfos {
let info = info.components(separatedBy: ",")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

루프 변수인 info와 동일한 이름으로 새로운 상수 info를 선언하고 있습니다 (변수 섀도잉). 이는 코드를 읽고 이해하기 어렵게 만들 수 있습니다. 파싱된 컴포넌트에 대해 infoComponents와 같이 다른 이름을 사용하는 것이 가독성을 높이는 데 도움이 됩니다. 이 제안을 적용하면 이어지는 코드에서 infoinfoComponents로 변경해야 합니다.

        let infoComponents = info.components(separatedBy: ",")

let startTime = toInt(info[0])
let endTime = toInt(info[1])
let playTime = endTime - startTime
let musicTitle = info[2]
let melody = info[3]
var music = ""

while music.count < playTime {
music += toShortString(melody)
}
Comment on lines +15 to +17

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

This while loop has a potential infinite loop vulnerability if toShortString(melody) returns an empty string and playTime is greater than 0, which can lead to CPU exhaustion and a Denial of Service (DoS). Additionally, toShortString(melody) is called in every iteration, which is an unnecessary repeated calculation as melody does not change within the loop. Consider pre-calculating shortMelody and adding a check for an empty string to prevent the infinite loop.

        let shortMelody = toShortString(melody)
        if !shortMelody.isEmpty {
            while music.count < playTime {
                music += shortMelody
            }
        }


if music.prefix(playTime).contains(toShortString(m)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

There's a potential crash vulnerability here: if endTime is less than startTime, playTime will be negative, causing a runtime crash when passed to prefix(_:). Ensure playTime is non-negative before calling prefix. Additionally, toShortString(m) is called repeatedly inside the for loop, which is inefficient as m does not change. Pre-calculating shortM outside the loop would improve performance.

        if playTime > 0, music.prefix(playTime).contains(toShortString(m)) {

if playTime > resultPlayTime {
result = musicTitle
resultPlayTime = playTime
resultStartTime = startTime
} else if playTime == resultPlayTime {
if startTime < resultStartTime {
result = musicTitle
resultPlayTime = playTime
resultStartTime = startTime
}
}
Comment on lines +20 to +30

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

문제의 조건에 따르면 재생 시간이 같을 경우, 먼저 입력된 음악 제목을 반환해야 합니다. 현재 코드는 startTime을 비교하여 더 일찍 시작한 음악을 선택하고 있는데, 이는 요구사항과 다릅니다. for 루프는 입력된 순서대로 순회하므로, 재생 시간이 더 긴 경우에만 결과를 갱신하면 '먼저 입력된' 조건이 자연스럽게 만족됩니다. 현재의 else if 블록은 잘못된 결과를 낼 수 있습니다. 아래와 같이 수정하여 재생 시간이 더 긴 경우에만 결과를 갱신하도록 하는 것이 올바릅니다. 이 수정과 함께 더 이상 필요 없는 resultStartTime 변수도 제거하는 것이 좋습니다.

            if playTime > resultPlayTime {
                result = musicTitle
                resultPlayTime = playTime
            }

}
}
return result
}

func toInt(_ timeString: String) -> Int {
let components = timeString.components(separatedBy: ":")
return (Int(components[0])! * 60) + Int(components[1])!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

This code exhibits insecure data handling. Force unwrapping (!) during Int conversion and direct array index access without bounds checking can lead to a runtime crash if timeString is not in the expected 'HH:MM' format. This vulnerability can be exploited to trigger a Denial of Service (DoS) attack. It's crucial to avoid force unwrapping for safer code and robust input validation.

    guard components.count >= 2, let hours = Int(components[0]), let minutes = Int(components[1]) else { return 0 }
    return (hours * 60) + minutes

}

func toShortString(_ string: String) -> String {
return string.replacingOccurrences(of: "C#", with: "c")
.replacingOccurrences(of: "D#", with: "d")
.replacingOccurrences(of: "F#", with: "f")
.replacingOccurrences(of: "G#", with: "g")
.replacingOccurrences(of: "A#", with: "a")
.replacingOccurrences(of: "B#", with: "C")
.replacingOccurrences(of: "E#", with: "F")
}