From 7ebdd4739aa3d9fa36b781c395bb74b40a4e5c0b Mon Sep 17 00:00:00 2001
From: MeiMei <30769358+mei23@users.noreply.github.com>
Date: Tue, 17 Aug 2021 17:25:19 +0900
Subject: [PATCH] Fix truncate (#7642)

---
 src/remote/activitypub/models/person.ts | 26 +++++++++++----------
 test/activitypub.ts                     | 30 +++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts
index 2270e05e3b..1b2d0bbdcf 100644
--- a/src/remote/activitypub/models/person.ts
+++ b/src/remote/activitypub/models/person.ts
@@ -34,6 +34,16 @@ const logger = apLogger;
 const nameLength = 128;
 const summaryLength = 2048;
 
+function truncate(input: string, size: number): string;
+function truncate(input: string | undefined, size: number): string | undefined;
+function truncate(input: string | undefined, size: number): string | undefined {
+	if (!input || input.length <= size) {
+		return input;
+	} else {
+		return input.substring(0, size);
+	}
+}
+
 /**
  * Validate and convert to actor object
  * @param x Fetched object
@@ -55,14 +65,6 @@ function validateActor(x: IObject, uri: string): IActor {
 		if (e) throw new Error(`invalid Actor: ${name} ${e.message}`);
 	};
 
-	const truncate = (input: string | undefined, size: number) => {
-		if (!input || input.length <= size) {
-			return input;
-		} else {
-			return input.substring(0, size);
-		}
-	};
-
 	validate('id', x.id, $.str.min(1));
 	validate('inbox', x.inbox, $.str.min(1));
 	validate('preferredUsername', x.preferredUsername, $.str.min(1).max(128).match(/^\w([\w-.]*\w)?$/));
@@ -152,7 +154,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 				bannerId: null,
 				createdAt: new Date(),
 				lastFetchedAt: new Date(),
-				name: person.name,
+				name: truncate(person.name, nameLength),
 				isLocked: !!person.manuallyApprovesFollowers,
 				isExplorable: !!person.discoverable,
 				username: person.preferredUsername,
@@ -170,7 +172,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 
 			await transactionalEntityManager.save(new UserProfile({
 				userId: user.id,
-				description: person.summary ? htmlToMfm(person.summary, person.tag) : null,
+				description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null,
 				url: getOneApHrefNullable(person.url),
 				fields,
 				birthday: bday ? bday[0] : null,
@@ -331,7 +333,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
 		followersUri: person.followers ? getApId(person.followers) : undefined,
 		featured: person.featured,
 		emojis: emojiNames,
-		name: person.name,
+		name: truncate(person.name, nameLength),
 		tags,
 		isBot: getApType(object) === 'Service',
 		isCat: (person as any).isCat === true,
@@ -364,7 +366,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
 	await UserProfiles.update({ userId: exist.id }, {
 		url: getOneApHrefNullable(person.url),
 		fields,
-		description: person.summary ? htmlToMfm(person.summary, person.tag) : null,
+		description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null,
 		birthday: bday ? bday[0] : null,
 		location: person['vcard:Address'] || null,
 	});
diff --git a/test/activitypub.ts b/test/activitypub.ts
index 5699a8c8de..24b8d13b85 100644
--- a/test/activitypub.ts
+++ b/test/activitypub.ts
@@ -70,4 +70,34 @@ describe('ActivityPub', () => {
 			assert.deepStrictEqual(note?.text, post.content);
 		});
 	});
+
+	describe('Truncate long name', () => {
+		const host = 'https://host1.test';
+		const preferredUsername = `${rndstr('A-Z', 4)}${rndstr('a-z', 4)}`;
+		const actorId = `${host}/users/${preferredUsername.toLowerCase()}`;
+
+		const name = rndstr('0-9a-z', 129);
+
+		const actor = {
+			'@context': 'https://www.w3.org/ns/activitystreams',
+			id: actorId,
+			type: 'Person',
+			preferredUsername,
+			name,
+			inbox: `${actorId}/inbox`,
+			outbox: `${actorId}/outbox`,
+		};
+
+		it('Actor', async () => {
+			const { MockResolver } = await import('./misc/mock-resolver');
+			const { createPerson } = await import('../src/remote/activitypub/models/person');
+
+			const resolver = new MockResolver();
+			resolver._register(actor.id, actor);
+
+			const user = await createPerson(actor.id, resolver);
+
+			assert.deepStrictEqual(user.name, actor.name.substr(0, 128));
+		});
+	});
 });