location.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package detect
  2. // Location represents a location in a file
  3. type Location struct {
  4. startLine int
  5. endLine int
  6. startColumn int
  7. endColumn int
  8. startLineIndex int
  9. endLineIndex int
  10. }
  11. func location(newlineIndices [][]int, raw string, matchIndex []int) Location {
  12. var (
  13. prevNewLine int
  14. location Location
  15. lineSet bool
  16. _lineNum int
  17. )
  18. start := matchIndex[0]
  19. end := matchIndex[1]
  20. // default startLineIndex to 0
  21. location.startLineIndex = 0
  22. // Fixes: https://github.com/zricethezav/gitleaks/issues/1037
  23. // When a fragment does NOT have any newlines, a default "newline"
  24. // will be counted to make the subsequent location calculation logic work
  25. // for fragments will no newlines.
  26. if len(newlineIndices) == 0 {
  27. newlineIndices = [][]int{
  28. {len(raw), len(raw) + 1},
  29. }
  30. }
  31. for lineNum, pair := range newlineIndices {
  32. _lineNum = lineNum
  33. newLineByteIndex := pair[0]
  34. if prevNewLine <= start && start < newLineByteIndex {
  35. lineSet = true
  36. location.startLine = lineNum
  37. location.endLine = lineNum
  38. location.startColumn = (start - prevNewLine) + 1 // +1 because counting starts at 1
  39. location.startLineIndex = prevNewLine
  40. location.endLineIndex = newLineByteIndex
  41. }
  42. if prevNewLine < end && end <= newLineByteIndex {
  43. location.endLine = lineNum
  44. location.endColumn = (end - prevNewLine)
  45. location.endLineIndex = newLineByteIndex
  46. }
  47. prevNewLine = pair[0]
  48. }
  49. if !lineSet {
  50. // if lines never get set then that means the secret is most likely
  51. // on the last line of the diff output and the diff output does not have
  52. // a newline
  53. location.startColumn = (start - prevNewLine) + 1 // +1 because counting starts at 1
  54. location.endColumn = (end - prevNewLine)
  55. location.startLine = _lineNum + 1
  56. location.endLine = _lineNum + 1
  57. // search for new line byte index
  58. i := 0
  59. for end+i < len(raw) {
  60. if raw[end+i] == '\n' {
  61. break
  62. }
  63. if raw[end+i] == '\r' {
  64. break
  65. }
  66. i++
  67. }
  68. location.endLineIndex = end + i
  69. }
  70. return location
  71. }