Changeset 492 in code for trunk


Ignore:
Timestamp:
Apr 13, 2021, 10:48:46 AM (4 years ago)
Author:
hubert
Message:

Make casemapping work over bytes instead of runes

Fixes a panic in partialCasemap when the input string was invalid UTF-8.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/irc.go

    r480 r492  
    430430// ascii casemapping.
    431431func casemapASCII(name string) string {
    432         var sb strings.Builder
    433         sb.Grow(len(name))
    434         for _, r := range name {
     432        nameBytes := []byte(name)
     433        for i, r := range nameBytes {
    435434                if 'A' <= r && r <= 'Z' {
    436                         r += 'a' - 'A'
    437                 }
    438                 sb.WriteRune(r)
    439         }
    440         return sb.String()
     435                        nameBytes[i] = r + 'a' - 'A'
     436                }
     437        }
     438        return string(nameBytes)
    441439}
    442440
     
    444442// rfc1459 casemapping.
    445443func casemapRFC1459(name string) string {
    446         var sb strings.Builder
    447         sb.Grow(len(name))
    448         for _, r := range name {
     444        nameBytes := []byte(name)
     445        for i, r := range nameBytes {
    449446                if 'A' <= r && r <= 'Z' {
    450                         r += 'a' - 'A'
     447                        nameBytes[i] = r + 'a' - 'A'
    451448                } else if r == '{' {
    452                         r = '['
     449                        nameBytes[i] = '['
    453450                } else if r == '}' {
    454                         r = ']'
     451                        nameBytes[i] = ']'
    455452                } else if r == '\\' {
    456                         r = '|'
     453                        nameBytes[i] = '|'
    457454                } else if r == '~' {
    458                         r = '^'
    459                 }
    460                 sb.WriteRune(r)
    461         }
    462         return sb.String()
     455                        nameBytes[i] = '^'
     456                }
     457        }
     458        return string(nameBytes)
    463459}
    464460
     
    466462// according to the rfc1459-strict casemapping.
    467463func casemapRFC1459Strict(name string) string {
    468         var sb strings.Builder
    469         sb.Grow(len(name))
    470         for _, r := range name {
     464        nameBytes := []byte(name)
     465        for i, r := range nameBytes {
    471466                if 'A' <= r && r <= 'Z' {
    472                         r += 'a' - 'A'
     467                        nameBytes[i] = r + 'a' - 'A'
    473468                } else if r == '{' {
    474                         r = '['
     469                        nameBytes[i] = '['
    475470                } else if r == '}' {
    476                         r = ']'
     471                        nameBytes[i] = ']'
    477472                } else if r == '\\' {
    478                         r = '|'
    479                 }
    480                 sb.WriteRune(r)
    481         }
    482         return sb.String()
     473                        nameBytes[i] = '|'
     474                }
     475        }
     476        return string(nameBytes)
    483477}
    484478
     
    498492
    499493func partialCasemap(higher casemapping, name string) string {
    500         nameFullyCM := higher(name)
    501         var sb strings.Builder
    502         sb.Grow(len(name))
    503         for i, r := range nameFullyCM {
    504                 if 'a' <= r && r <= 'z' {
    505                         r = rune(name[i])
    506                 }
    507                 sb.WriteRune(r)
    508         }
    509         return sb.String()
     494        nameFullyCM := []byte(higher(name))
     495        nameBytes := []byte(name)
     496        for i, r := range nameBytes {
     497                if !('A' <= r && r <= 'Z') && !('a' <= r && r <= 'z') {
     498                        nameBytes[i] = nameFullyCM[i]
     499                }
     500        }
     501        return string(nameBytes)
    510502}
    511503
Note: See TracChangeset for help on using the changeset viewer.