Fix inconsistent behavior from String#first/#last

While calling String#first or String#last with zero or a Fixnum < the
string's length returns a new string, a Fixnum >= the string's length
returns the string itself. This inconsistency can lead to inadvertent
mutation of a string.
Merge pull request #14799 from ernie/string-first-last-fix

Fix inconsistent behavior from String#first/#last