Skip to contentSkip to conversation

Clean up and fix errors in strncpy -> strlcpy conversion

PATCH In review Aron Griffis 4 participants 9 messages Jan 30, 2007

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Clean up and fix errors in strncpy -> strlcpy conversion

This patch is for the staging tree. Please apply.

# HG changeset patch
# User Aron Griffis <[email protected]>
# Date 1170118368 18000
# Node ID 23560e2248fd267bad6490113ed52d0a27d7e219 # Parent 5e3b47bcc311e7698959f1fa79c4654190593499 Clean up and fix errors in strncpy -> strlcpy conversion

xen/arch/ia64/xen/dom_fw.c +22 -27
diff -r 5e3b47bcc311 -r 23560e2248fd xen/arch/ia64/xen/dom_fw.c
@@ -333,13 +333,13 @@ dom_fw_fake_acpi(struct domain *d, struc
 	memset(tables, 0, sizeof(struct fake_acpi_tables));
 
 	/* setup XSDT (64bit version of RSDT) */
-	strlcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
+	memcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
 	/* XSDT points to both the FADT and the MADT, so add one entry */
 	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(u64);
 	xsdt->revision = 1;
-	strlcpy(xsdt->oem_id, "XEN", sizeof(xsdt->oem_id));
-	strlcpy(xsdt->oem_table_id, "Xen/ia64", sizeof(xsdt->oem_table_id));
-	strlcpy(xsdt->asl_compiler_id, "XEN", sizeof(xsdt->asl_compiler_id));
+	safe_strcpy(xsdt->oem_id, "XEN");
+	safe_strcpy(xsdt->oem_table_id, "Xen/ia64");
+	safe_strcpy(xsdt->asl_compiler_id, "XEN");
 	xsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
@@ -349,16 +349,16 @@ dom_fw_fake_acpi(struct domain *d, struc
 	xsdt->checksum = generate_acpi_checksum(xsdt, xsdt->length);
 
 	/* setup FADT */
-	strlcpy(fadt->signature, FADT_SIG, sizeof(fadt->signature));
+	memcpy(fadt->signature, FADT_SIG, sizeof(fadt->signature));
 	fadt->length = sizeof(struct fadt_descriptor_rev2);
 	fadt->revision = FADT2_REVISION_ID;
-	strlcpy(fadt->oem_id, "XEN", sizeof(fadt->oem_id));
-	strlcpy(fadt->oem_table_id, "Xen/ia64", sizeof(fadt->oem_table_id));
-	strlcpy(fadt->asl_compiler_id, "XEN", sizeof(fadt->asl_compiler_id));
+	safe_strcpy(fadt->oem_id, "XEN");
+	safe_strcpy(fadt->oem_table_id, "Xen/ia64");
+	safe_strcpy(fadt->asl_compiler_id, "XEN");
 	fadt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
-	strlcpy(facs->signature, FACS_SIG, sizeof(facs->signature));
+	memcpy(facs->signature, FACS_SIG, sizeof(facs->signature));
 	facs->version = 1;
 	facs->length = sizeof(struct facs_descriptor_rev2);
 
@@ -386,8 +386,8 @@ dom_fw_fake_acpi(struct domain *d, struc
 	fadt->checksum = generate_acpi_checksum(fadt, fadt->length);
 
 	/* setup RSDP */
-	strlcpy(rsdp->signature, RSDP_SIG, sizeof(rsdp->signature));
-	strlcpy(rsdp->oem_id, "XEN", sizeof(rsdp->oem_id));
+	safe_strcpy(rsdp->signature, RSDP_SIG);
+	safe_strcpy(rsdp->oem_id, "XEN");
 	rsdp->revision = 2; /* ACPI 2.0 includes XSDT */
 	rsdp->length = sizeof(struct acpi20_table_rsdp);
 	rsdp->xsdt_address = ACPI_TABLE_MPA(xsdt);
@@ -397,11 +397,11 @@ dom_fw_fake_acpi(struct domain *d, struc
 	rsdp->ext_checksum = generate_acpi_checksum(rsdp, rsdp->length);
 
 	/* setup DSDT with trivial namespace. */ 
-	strlcpy(dsdt->signature, DSDT_SIG, sizeof(dsdt->signature));
+	safe_strcpy(dsdt->signature, DSDT_SIG);
 	dsdt->revision = 1;
-	strlcpy(dsdt->oem_id, "XEN", sizeof(dsdt->oem_id));
-	strlcpy(dsdt->oem_table_id, "Xen/ia64", sizeof(dsdt->oem_table_id));
-	strlcpy(dsdt->asl_compiler_id, "XEN", sizeof(dsdt->asl_compiler_id));
+	safe_strcpy(dsdt->oem_id, "XEN");
+	safe_strcpy(dsdt->oem_table_id, "Xen/ia64");
+	safe_strcpy(dsdt->asl_compiler_id, "XEN");
 	dsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
@@ -409,7 +409,7 @@ dom_fw_fake_acpi(struct domain *d, struc
 	tables->aml[0] = 0x10; /* Scope */
 	tables->aml[1] = 0x40; /* length/offset to next object (patched) */
 	tables->aml[2] = 0x00;
-	strlcpy((char *)&tables->aml[3], "_SB_", 5);
+	memcpy(&tables->aml[3], "_SB_", 4);
 
 	/* The processor object isn't absolutely necessary, revist for SMP */
 	aml_len = 7;
@@ -437,14 +437,11 @@ dom_fw_fake_acpi(struct domain *d, struc
 	dsdt->checksum = generate_acpi_checksum(dsdt, dsdt->length);
 
 	/* setup MADT */
-	strlcpy(madt->header.signature, APIC_SIG, sizeof(madt->header.signature));
+	memcpy(madt->header.signature, APIC_SIG, sizeof(madt->header.signature));
 	madt->header.revision = 2;
-	strlcpy(madt->header.oem_id, "XEN",
-		sizeof(madt->header.oem_id));
-	strlcpy(madt->header.oem_table_id, "Xen/ia64",
-		sizeof(madt->header.oem_table_id));
-	strlcpy(madt->header.asl_compiler_id, "XEN",
-		sizeof(madt->header.asl_compiler_id));
+	safe_strcpy(madt->header.oem_id, "XEN");
+	safe_strcpy(madt->header.oem_table_id, "Xen/ia64");
+	safe_strcpy(madt->header.asl_compiler_id, "XEN");
 	madt->header.asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
@@ -763,10 +760,8 @@ dom_fw_init(struct domain *d,
 	tables->sal_systab.sal_rev_major = 0;
 	tables->sal_systab.entry_count = 2;
 
-	strlcpy((char *)tables->sal_systab.oem_id, "Xen/ia64",
-		sizeof(tables->sal_systab.oem_id));
-	strlcpy((char *)tables->sal_systab.product_id, "Xen/ia64",
-		sizeof(tables->sal_systab.product_id));
+	safe_strcpy((char *)tables->sal_systab.oem_id, "Xen/ia64");
+	safe_strcpy((char *)tables->sal_systab.product_id, "Xen/ia64");
 
 	/* PAL entry point: */
 	tables->sal_ed.type = SAL_DESC_ENTRY_POINT;
xen/arch/ia64/xen/oprofile/perfmon.c +0 -1
diff -r 5e3b47bcc311 -r 23560e2248fd xen/arch/ia64/xen/oprofile/perfmon.c
@@ -120,7 +120,6 @@ xenoprof_arch_init(int *num_events, int 
 {
     *num_events = 0;
     strlcpy(cpu_type, get_cpu_type(), XENOPROF_CPU_TYPE_SIZE);
-    cpu_type[XENOPROF_CPU_TYPE_SIZE - 1] = '\0';
 
     *is_primary = 0;
     if (xenoprof_primary_profiler == NULL) {
#1 lore raw
Quoted 21 lines · Aron Griffis

This patch is for the staging tree. Please apply.

# HG changeset patch
# User Aron Griffis <[email protected]>
# Date 1170118368 18000
# Node ID 23560e2248fd267bad6490113ed52d0a27d7e219 # Parent 5e3b47bcc311e7698959f1fa79c4654190593499 Clean up and fix errors in strncpy -> strlcpy conversion

diff -r 5e3b47bcc311 -r 23560e2248fd xen/arch/ia64/xen/dom_fw.c

xen/arch/ia64/xen/dom_fw.c +1 -1
@@ -333,13 +333,13 @@ dom_fw_fake_acpi(struct domain *d, struc
 	memset(tables, 0, sizeof(struct fake_acpi_tables));
 
 	/* setup XSDT (64bit version of RSDT) */
-	strlcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
+	memcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
 	/* XSDT points to both the FADT and the MADT, so add one entry */

xen/arch/ia64/xen/dom_fw.c dom_fw_fake_acpi(struct domain *d, struc · line 344

Quoted 10 lines
xen/arch/ia64/xen/dom_fw.c +3 -3
 	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(u64);
 	xsdt->revision = 1;
-	strlcpy(xsdt->oem_id, "XEN", sizeof(xsdt->oem_id));
-	strlcpy(xsdt->oem_table_id, "Xen/ia64", sizeof(xsdt->oem_table_id));
-	strlcpy(xsdt->asl_compiler_id, "XEN", sizeof(xsdt->asl_compiler_id));
+	safe_strcpy(xsdt->oem_id, "XEN");
+	safe_strcpy(xsdt->oem_table_id, "Xen/ia64");
+	safe_strcpy(xsdt->asl_compiler_id, "XEN");
 	xsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();

In my patch, safe_strcpy() is gone. And anyway, if safe_strcpy works as expected, then apart from the return value there's no difference to strlcpy().

The ACPI header fields simply need one more byte for the NUL.

Christoph

#2 lore raw
Quoted 3 lines · Christoph Egger

In my patch, safe_strcpy() is gone. And anyway, if safe_strcpy works as expected, then apart from the return value there's no difference to strlcpy().

I kept safe_strcpy() now implemented over strlcpy() and returns non-zero if the result is truncated. When writing into a char array this is less redundant than writing (strlcpy(d,s,sizeof(d) >= sizeof(d)) where 'd' is often some annoyingly long structural name.

-- Keir

#3 lore raw
In reply to Christoph Egger

Christoph Egger wrote: [Tue Jan 30 2007, 03:23:07AM EST]

Quoted 28 lines · Aron Griffis
Quoted 27 lines

This patch is for the staging tree. Please apply.

# HG changeset patch
# User Aron Griffis <[email protected]>
# Date 1170118368 18000
# Node ID 23560e2248fd267bad6490113ed52d0a27d7e219 # Parent 5e3b47bcc311e7698959f1fa79c4654190593499 Clean up and fix errors in strncpy -> strlcpy conversion

diff -r 5e3b47bcc311 -r 23560e2248fd xen/arch/ia64/xen/dom_fw.c

xen/arch/ia64/xen/dom_fw.c +2 -4
@@ -333,13 +333,13 @@ dom_fw_fake_acpi(struct domain *d, struc
 	memset(tables, 0, sizeof(struct fake_acpi_tables));
 
 	/* setup XSDT (64bit version of RSDT) */
-	strlcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
+	memcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
 	/* XSDT points to both the FADT and the MADT, so add one entry */
 	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(u64);
 	xsdt->revision = 1;
-	strlcpy(xsdt->oem_id, "XEN", sizeof(xsdt->oem_id));
-	strlcpy(xsdt->oem_table_id, "Xen/ia64", sizeof(xsdt->oem_table_id));
-	strlcpy(xsdt->asl_compiler_id, "XEN", sizeof(xsdt->asl_compiler_id));
+	safe_strcpy(xsdt->oem_id, "XEN");
Quoted 8 lines

xen/arch/ia64/xen/dom_fw.c dom_fw_fake_acpi(struct domain *d, struc · line 344

Quoted 4 lines
xen/arch/ia64/xen/dom_fw.c +2 -0
+	safe_strcpy(xsdt->oem_table_id, "Xen/ia64");
+	safe_strcpy(xsdt->asl_compiler_id, "XEN");
 	xsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();

In my patch, safe_strcpy() is gone. And anyway, if safe_strcpy works as expected, then apart from the return value there's no difference to strlcpy().

You're confusing the cleanups with the bugfixes. Any use of safe_strcpy() in my patch was just cleanup.

The bugfixes are on the signature fields (the first change quoted above), which I changed to use memcpy since strlcpy adds an unwanted NUL.

Aron

#4 lore raw
Quoted 39 lines · Aron Griffis

Christoph Egger wrote: [Tue Jan 30 2007, 03:23:07AM EST]

Quoted 28 lines · Aron Griffis
Quoted 27 lines

This patch is for the staging tree. Please apply.

# HG changeset patch
# User Aron Griffis <[email protected]>
# Date 1170118368 18000
# Node ID 23560e2248fd267bad6490113ed52d0a27d7e219 # Parent 5e3b47bcc311e7698959f1fa79c4654190593499 Clean up and fix errors in strncpy -> strlcpy conversion

diff -r 5e3b47bcc311 -r 23560e2248fd xen/arch/ia64/xen/dom_fw.c

xen/arch/ia64/xen/dom_fw.c +2 -4
@@ -333,13 +333,13 @@ dom_fw_fake_acpi(struct domain *d, struc
 	memset(tables, 0, sizeof(struct fake_acpi_tables));
 
 	/* setup XSDT (64bit version of RSDT) */
-	strlcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
+	memcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
 	/* XSDT points to both the FADT and the MADT, so add one entry */
 	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(u64);
 	xsdt->revision = 1;
-	strlcpy(xsdt->oem_id, "XEN", sizeof(xsdt->oem_id));
-	strlcpy(xsdt->oem_table_id, "Xen/ia64", sizeof(xsdt->oem_table_id));
-	strlcpy(xsdt->asl_compiler_id, "XEN", sizeof(xsdt->asl_compiler_id));
+	safe_strcpy(xsdt->oem_id, "XEN");
Quoted 8 lines

xen/arch/ia64/xen/dom_fw.c dom_fw_fake_acpi(struct domain *d, struc · line 344

Quoted 4 lines
xen/arch/ia64/xen/dom_fw.c +2 -0
+	safe_strcpy(xsdt->oem_table_id, "Xen/ia64");
+	safe_strcpy(xsdt->asl_compiler_id, "XEN");
 	xsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();

In my patch, safe_strcpy() is gone. And anyway, if safe_strcpy works as expected, then apart from the return value there's no difference to strlcpy().

Quoted 6 lines

You're confusing the cleanups with the bugfixes. Any use of safe_strcpy() in my patch was just cleanup.

The bugfixes are on the signature fields (the first change quoted above), which I changed to use memcpy since strlcpy adds an unwanted NUL.

I am waiting for whatever appears next in the public tree. Then I continue on whatever is missing or got broken.

#5 lore raw
In reply to Aron Griffis
Quoted 39 lines · Aron Griffis

Christoph Egger wrote: [Tue Jan 30 2007, 03:23:07AM EST]

Quoted 28 lines · Aron Griffis
Quoted 27 lines

This patch is for the staging tree. Please apply.

# HG changeset patch
# User Aron Griffis <[email protected]>
# Date 1170118368 18000
# Node ID 23560e2248fd267bad6490113ed52d0a27d7e219 # Parent 5e3b47bcc311e7698959f1fa79c4654190593499 Clean up and fix errors in strncpy -> strlcpy conversion

diff -r 5e3b47bcc311 -r 23560e2248fd xen/arch/ia64/xen/dom_fw.c

xen/arch/ia64/xen/dom_fw.c +2 -4
@@ -333,13 +333,13 @@ dom_fw_fake_acpi(struct domain *d, struc
 	memset(tables, 0, sizeof(struct fake_acpi_tables));
 
 	/* setup XSDT (64bit version of RSDT) */
-	strlcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
+	memcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
 	/* XSDT points to both the FADT and the MADT, so add one entry */
 	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(u64);
 	xsdt->revision = 1;
-	strlcpy(xsdt->oem_id, "XEN", sizeof(xsdt->oem_id));
-	strlcpy(xsdt->oem_table_id, "Xen/ia64", sizeof(xsdt->oem_table_id));
-	strlcpy(xsdt->asl_compiler_id, "XEN", sizeof(xsdt->asl_compiler_id));
+	safe_strcpy(xsdt->oem_id, "XEN");
Quoted 8 lines

xen/arch/ia64/xen/dom_fw.c dom_fw_fake_acpi(struct domain *d, struc · line 344

Quoted 4 lines
xen/arch/ia64/xen/dom_fw.c +2 -0
+	safe_strcpy(xsdt->oem_table_id, "Xen/ia64");
+	safe_strcpy(xsdt->asl_compiler_id, "XEN");
 	xsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();

In my patch, safe_strcpy() is gone. And anyway, if safe_strcpy works as expected, then apart from the return value there's no difference to strlcpy().

Quoted 6 lines

You're confusing the cleanups with the bugfixes. Any use of safe_strcpy() in my patch was just cleanup.

The bugfixes are on the signature fields (the first change quoted above), which I changed to use memcpy since strlcpy adds an unwanted NUL.

Aron: If the above patch is still correct (against CS 13703), please resend it for Keir to apply.

Christoph

#6 lore raw
Quoted 9 lines · Christoph Egger
Quoted 6 lines

You're confusing the cleanups with the bugfixes. Any use of safe_strcpy() in my patch was just cleanup.

The bugfixes are on the signature fields (the first change quoted above), which I changed to use memcpy since strlcpy adds an unwanted NUL.

Aron: If the above patch is still correct (against CS 13703), please resend it for Keir to apply.

The original patch still applies cleanly to xen-unstable so I'll apply it without a resend.

-- Keir

#7 lore raw

Sorry, but this is still wrong. Some of these fields we're filling
completely, and tagging a NUL at the end just doesn't work. I suggest replacing all the safe_strcpy()s with memcpy()s. Patch below. Thanks,

Alex

---

xen/arch/ia64/xen/dom_fw.c +17 -17
diff -r b4121f051773 xen/arch/ia64/xen/dom_fw.c
@@ -337,9 +337,9 @@ dom_fw_fake_acpi(struct domain *d, struc
 	/* XSDT points to both the FADT and the MADT, so add one entry */
 	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(u64);
 	xsdt->revision = 1;
-	safe_strcpy(xsdt->oem_id, "XEN");
-	safe_strcpy(xsdt->oem_table_id, "Xen/ia64");
-	safe_strcpy(xsdt->asl_compiler_id, "XEN");
+	memcpy(xsdt->oem_id, "XEN", 3);
+	memcpy(xsdt->oem_table_id, "Xen/ia64", 8);
+	memcpy(xsdt->asl_compiler_id, "XEN", 3);
 	xsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
@@ -352,9 +352,9 @@ dom_fw_fake_acpi(struct domain *d, struc
 	memcpy(fadt->signature, FADT_SIG, sizeof(fadt->signature));
 	fadt->length = sizeof(struct fadt_descriptor_rev2);
 	fadt->revision = FADT2_REVISION_ID;
-	safe_strcpy(fadt->oem_id, "XEN");
-	safe_strcpy(fadt->oem_table_id, "Xen/ia64");
-	safe_strcpy(fadt->asl_compiler_id, "XEN");
+	memcpy(fadt->oem_id, "XEN", 3);
+	memcpy(fadt->oem_table_id, "Xen/ia64", 8);
+	memcpy(fadt->asl_compiler_id, "XEN", 3);
 	fadt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
@@ -386,8 +386,8 @@ dom_fw_fake_acpi(struct domain *d, struc
 	fadt->checksum = generate_acpi_checksum(fadt, fadt->length);
 
 	/* setup RSDP */
-	safe_strcpy(rsdp->signature, RSDP_SIG);
-	safe_strcpy(rsdp->oem_id, "XEN");
+	memcpy(rsdp->signature, RSDP_SIG, strlen(RSDP_SIG));
+	memcpy(rsdp->oem_id, "XEN", 3);
 	rsdp->revision = 2; /* ACPI 2.0 includes XSDT */
 	rsdp->length = sizeof(struct acpi20_table_rsdp);
 	rsdp->xsdt_address = ACPI_TABLE_MPA(xsdt);
@@ -397,11 +397,11 @@ dom_fw_fake_acpi(struct domain *d, struc
 	rsdp->ext_checksum = generate_acpi_checksum(rsdp, rsdp->length);
 
 	/* setup DSDT with trivial namespace. */ 
-	safe_strcpy(dsdt->signature, DSDT_SIG);
+	memcpy(dsdt->signature, DSDT_SIG, strlen(DSDT_SIG));
 	dsdt->revision = 1;
-	safe_strcpy(dsdt->oem_id, "XEN");
-	safe_strcpy(dsdt->oem_table_id, "Xen/ia64");
-	safe_strcpy(dsdt->asl_compiler_id, "XEN");
+	memcpy(dsdt->oem_id, "XEN", 3);
+	memcpy(dsdt->oem_table_id, "Xen/ia64", 8);
+	memcpy(dsdt->asl_compiler_id, "XEN", 3);
 	dsdt->asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
@@ -439,9 +439,9 @@ dom_fw_fake_acpi(struct domain *d, struc
 	/* setup MADT */
 	memcpy(madt->header.signature, APIC_SIG, sizeof(madt->header.signature));
 	madt->header.revision = 2;
-	safe_strcpy(madt->header.oem_id, "XEN");
-	safe_strcpy(madt->header.oem_table_id, "Xen/ia64");
-	safe_strcpy(madt->header.asl_compiler_id, "XEN");
+	memcpy(madt->header.oem_id, "XEN", 3);
+	memcpy(madt->header.oem_table_id, "Xen/ia64", 8);
+	memcpy(madt->header.asl_compiler_id, "XEN", 3);
 	madt->header.asl_compiler_revision = (xen_major_version() << 16) |
 		xen_minor_version();
 
@@ -760,8 +760,8 @@ dom_fw_init(struct domain *d,
 	tables->sal_systab.sal_rev_major = 0;
 	tables->sal_systab.entry_count = 2;
 
-	safe_strcpy((char *)tables->sal_systab.oem_id, "Xen/ia64");
-	safe_strcpy((char *)tables->sal_systab.product_id, "Xen/ia64");
+	memcpy((char *)tables->sal_systab.oem_id, "Xen/ia64", 8);
+	memcpy((char *)tables->sal_systab.product_id, "Xen/ia64", 8);
 
 	/* PAL entry point: */
 	tables->sal_ed.type = SAL_DESC_ENTRY_POINT;
#8 lore raw
Quoted 3 lines · Alex Williamson

Sorry, but this is still wrong. Some of these fields we're filling
completely, and tagging a NUL at the end just doesn't work. I suggest replacing all the safe_strcpy()s with memcpy()s. Patch below. Thanks,

Given the ACPI fields aren't proper C strings (as you say, they don't have to be NUL terminated) avoiding use of str* functions makes sense.

-- Keir