Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/LdifDotNet/RfcGrammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ internal static class RfcGrammar
/// </summary>
internal static readonly UTF8Encoding StrictUtf8 = new(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);

/// <summary>RFC 4512 numericoid / RFC 2849 ldap-oid: 1*DIGIT *("." 1*DIGIT).</summary>
/// <summary>
/// Numeric OID, deliberately the looser RFC 2849 ldap-oid grammar
/// (1*DIGIT *("." 1*DIGIT)) rather than RFC 4512's numericoid: leading-zero
/// arcs and single-arc OIDs are accepted. Correct per spec on every LDIF
/// boundary, and matched to slapd on the schema boundary — slaptest 2.6
/// accepts 01.2.3.4.5, 1.02.3, and bare 1 in attributetype directives, so
/// tightening this would reject files slapd loads. Pinned by tests; do not
/// "fix" toward RFC 4512 without re-probing slapd.
/// </summary>
internal static bool IsNumericOid(string text)
{
bool expectDigit = true;
Expand Down
1 change: 1 addition & 0 deletions tests/LdifDotNet.Tests/AttributeDescriptionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public void HasOption_matches_whole_options_case_insensitively(string descriptio
[Theory]
[InlineData("cn", true)]
[InlineData("2.5.4.3", true)]
[InlineData("01.2.3", true)] // RFC 2849 ldap-oid allows leading zeros — deliberate, see RfcGrammar.IsNumericOid
[InlineData("userCertificate;binary", true)]
[InlineData("cn;lang-en;binary", true)]
[InlineData("", false)]
Expand Down
17 changes: 17 additions & 0 deletions tests/LdifDotNet.Tests/SchemaParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@ public static TheoryData<string> SchemaFiles()
return data;
}

[Theory]
[InlineData("01.2.3.4.5")] // leading-zero arc — illegal per RFC 4512 numericoid
[InlineData("1.02.3")] // interior leading zero
[InlineData("1")] // single arc — RFC 4512 requires at least two
public void Oid_leniency_matches_slapd_not_rfc4512(string oid)
{
// Deliberate: IsNumericOid implements RFC 2849's looser ldap-oid, and
// slapd is exactly as loose — slaptest (OpenLDAP 2.6.10, 2026-08-03)
// accepted attributetype directives with every OID shape below.
// Tightening to RFC 4512's numericoid would reject schema files slapd
// loads, breaking the tolerant-reader / slapd-compatibility invariant.
var schema = LdapSchema.Parse(
$"attributetype ( {oid} NAME 'probeAttr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )\n");

Assert.Equal(oid, schema.AttributeTypes[0].Oid);
}

[Fact]
public void Ldapsyntax_directive_parses_in_file_mode()
{
Expand Down