@@ -697,10 +697,25 @@ VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
697697 char *start = idris_utf8_advance(str_val, offset_val);
698698 char *end = idris_utf8_advance(start, length_val);
699699 size_t sz = end - start;
700− String * newstr = allocStr(vm, sz, 0);
701− memcpy(newstr->str, start, sz);
702− newstr->str[sz] = '\0';
703− return (VAL)newstr;
700+
701+ if (space(vm, sz)) {
702+ String * newstr = allocStr(vm, sz, 0);
703+ memcpy(newstr->str, start, sz);
704+ newstr->str[sz] = '\0';
705+ return (VAL)newstr;
706+ } else {
707+ // Need to copy into an intermediate string before allocating,
708+ // because if there's no enough space then allocating will move the
709+ // original string!
710+ char* cpystr = malloc(sz);
711+ memcpy(cpystr, start, sz);
712+
713+ String * newstr = allocStr(vm, sz, 0);
714+ memcpy(newstr->str, cpystr, sz);
715+ newstr->str[sz] = '\0';
716+ free(cpystr);
717+ return (VAL)newstr;
718+ }
704719 }
705720}
706721